コマンドラインからのグラフィックス操作 第2回

LinuxでImageMagickを使うヒントと手法

大規模なバッチ処理にはコマンドライン・ツールが一番ですが、イメージ操作も例外ではありません。コマンドラインやスクリプトで多くのファイルを簡単に処理できるということをWeb開発者やアドミニストレーターは高く評価しています。本稿ではプログラマーのMichael Stillが例を挙げながらImageMagickスイートの説明を続けます。今回は画像のコーナーに丸みをつけたりロゴを追加したり、画像に枠(frame)や境界(border)を追加したり、複数ページに渡るファイルを、(Adobe社のPDFを含めて)フォーマット変換する方法について説明します。

Michael Still (mikal@stillhq.com), Senior software engineer, Tower Software

Michael StillMichaelは、数年間オーストラリアの政府機関向けに大規模な画像データベースの管理や開発を行うなど、画像処理の分野に従事してきました。現在は世界最先端のEDMSやTRIMというレコード管理パッケージの製造を行うTower Software社に勤務しています。またオープン・ソースのPDF生成APIであるPandaや、他のオープンソース・コードの開発者でもあります。



2004年 3月 16日

昨年私はdeveloperWorksに、ImageMagickを使ったコマンドラインからの画像操作についての記事を書きました。記事は非常に好評でしたが、それ以来私はImageMagickに関する質問の電子メールを何通も受け取りました。この記事では前回の記事で説明したテクニックを拡張し、今まで受けた質問に対してもできるだけお答えしたいと思います。IBM DeveloperWorks でImageMagickに関して読むのはこの記事が初めての方は、前回の記事もぜひ目を通してください。リンクは参考文献にあります。

この記事では特定な問題を例として取り上げる形式をとっていますが、考え方は他の問題領域にも適用できるものです。これは前回の記事で取ったのと同じ手法です。ここで説明する手法は前回説明した手法と組み合わせて使う事もできます。

この記事で説明していることを実現する方法は、他にもたくさんあることに注意してください。ここでは、私が使ってみてうまく行った方法についてのみ説明します。世の中にたくさんある他のツールが使えないというわけではありません。ただ私は単に今使っているものに満足しているので、それをご紹介しているにすぎません。

コーナーに丸みをつける

Mac OS/Xや色々なWebサイトを見た事があれば、非常にうまく画像に丸みがついているのに気がついたでしょう。どうすればImageMagickでこれが実現できるでしょう? ではここで、compositeコマンドを使えばうまくできる事をお見せしましょう。

ちょっとその前に、どんな方針で進もうとしているのかを説明しましょう。考えてみれば分かると思うのですが、丸みの付いたコーナーを持つ画像は、標準であらかじめ用意されたコーナーを使い、それを元の画像の上に重ね合わせることで作る事ができるのです。実際には全部のコーナーを丸める必要はなく、角張ったコーナーにしたり、もっと素敵なコーナーにしたりすることもできるのです。

コーナーの見せたくない部分を透明にすることを覚えておいてください。この透明操作によって、コーナーを付け加えようとしている画像が透けて見えるのです。xviewのような一部の画像ビューアーは黒やその他の色で透明を見せるので、これにはちょっと混乱するかも知れません。

GIMP

GIMP (GNU Image Manipulation Package)は非常に便利なラスター・グラフィックス・エディターで、Adobe Photoshopとよく似ています。画像をちょっと加工したり、自分で新しい画像を作ったりするのには重宝です。GimpやGimp関連の資料へのリンクについては参考文献を見てください。

図1. xviewで表示した、丸みをつけたコーナー
A rounded corner with xview

実際のコーナー画像は、画像の上に重ね合わせた時にもっとはっきりするので今は気にしない事にしましょう。前回作ったサムネイルに、Canberraの湖の眺めがあります。コーナーを丸めないと、サムネイルはこんな風に見えます。

図2. Burley Griffin湖
A lake view

ある画像を別の画像に重ねるにはcompositeコマンドを使います。何が起きるか、一つのコーナーだけ処理してみましょう。

composite -gravity NorthEast rounded-ne.png lake.png lake-1.png

ここでgravity(重心)引数は、重ね合わせた画像(私たちの例では丸みをつけたコーナー)を画像のどこに置くかを定義します。具体的にこのコマンドを実行すると次ような画像が得られます。

図3. コーナーの一つに丸みをつけたBurley Griffin湖
A lake view

では他のコーナーもやってみましょう。

composite -gravity NorthEast rounded-ne.png lake.png lake-1.png
composite -gravity NorthWest rounded-nw.png lake-1.png lake-2.png
composite -gravity SouthEast rounded-se.png lake-2.png lake-3.png
composite -gravity SouthWest rounded-sw.png lake-3.png lake-4.png

これで次のように画像が仕上がります。

図4. コーナーに丸みをつけたBurley Griffin湖
A lake view

私にはずいぶんカッコ良くなったと思えます。注意して欲しいのですが、コーナーが丸くなければならない理由はありません。角張ったコーナーの方が良ければ、それも同じようにできます。単にコーナー画像をビットマップ・エディターで変更すればよいのです。実際、コーナーの代わりに自分の好きなロゴを重ね合わせることもできるのです。

私が使った丸みつきコーナーをお使いになりたければ、記事の終わりにある参考文献を見てください。

さてこれで、あるディレクトリ上に置かれた全てのpng画像のコーナーに丸みをつけられるスクリプトができます。

for img in *.pngdo composite -gravity NorthEast rounded-ne.png $img.png $img-1.png
composite -gravity NorthWest rounded-nw.png $img-1.png $img-2.png
composite -gravity SouthEast rounded-se.png $img-2.png $img-3.png
composite -gravity SouthWest rounded-sw.png $img-3.png $img-4.png
done


画像を枠で囲う

何人かの読者からいただいた質問に、画像を枠で囲えないのかというものもありました。これもImageMagickを使えば比較的簡単です。

盛り上げた縁取り(raised border)、または窪ませた縁取り(lowered border)

枠取りの最初として盛り上げた縁取りまたは窪ませた縁取りについて説明します。この効果を得るには画像の端の色を加工し、端の部分がその周囲よりも盛り上がっているか、押し下げられて見えるようにします。最初にサイズを規定する必要があります。最初に水平サイズを規定し、次に垂直サイズを規定します。こうしたサイズは規定したサイズの2倍が、その画像のその方向の大きさと同じかそれ以下である、という規則に従う必要があります。例えば、画像の垂直サイズの半分より大きな垂直サイズを持つ枠を規定する事はできません。つまり、基本的には元の画像よりも大きな枠を作る事はできない、ということになります。

盛り上げた縁取りを作るには、-raiseコマンドライン引数を使います。例えば、5ピクセル X 5ピクセルの縁取りを作るには次を実行します。

convert -raise 5x5 tree.png tree-raised.png

これを実行すると次のような画像になります。

図5. 盛り上がった縁取りのついた画像
Some trees by a bay with a raised border

窪んだ縁取りをつけるには、今度は +raiseコマンドライン引数を使います。例えば

convert +raise 5x5 tree.png tree-lowered.png

これで、少し違った仕上げの画像ができます。

図6. 窪んだ縁取りのついた画像
Some trees by a bay with a lowered border

簡単な、色のついた縁取り

もう少し簡単なものにしたいのであれば、ベタで色がついただけの縁取りが良いかも知れません。これもImageMagickでできます。

convert -bordercolor red -border 5x5 flower.png flower-border.png

これで次のような画像になります。

図7. 赤い縁取りのついた画像
Some flowers with a red border

コマンドラインでどんな縁取り色を指定できるでしょうか? うーん、そのリストは長すぎてこの記事に収まりません。次のコマンドを実行すればそのリストのコピーを見る事ができます。

convert -list color

素焼きから木肌、トウモロコシの穂毛から貝殻まで、683種類もの「基本色」があり、さらに次のようなフォーマットを自由に使って自分で色を指定する事もできるのです(ここでRは赤の値、Gは緑、Bは青、Aはアルファ(透明)値を表します)。

  • #RGB - (R、G、Bは各4ビットの16進数)
  • #RRGGBB -(各8ビット)
  • #RRRGGGBBB -(各12ビット)
  • #RRRRGGGGBBBB -(各16ビット)
  • #RGBA -(各4ビット)
  • #RRGGBBAA -(各8ビット)
  • #RRRGGGBBBAAA -(各12ビット)
  • #RRRRGGGGBBBBAAAA -(各16ビット)
  • rgb(r,g,b) -(r、g、bは十進数)
  • rgba(r,g,b,a) -(r、g、b、aは十進数)

もっと複雑な枠を作る

次に-frameコマンドライン引数を使ってもう少し複雑な枠を作ってみましょう。最初に先の例で作った縁取りと(色以外は)同じ、簡単な枠を追加します。

convert -mattecolor black -frame 5x5 beach.png beach-frame.png

引数は-bordercolorや-borderではなく-mattcolorと-frameですが、他はborderコマンドと同じです。

図8. 簡単な黒の縁取
A picture of the beach with a simple black frame

今度は -raiseコマンドでつけたのと似た灰色の影(gray shading)を付けて、少し複雑にしてみます。

convert -mattecolor black -frame 5x5+2 beach.png beach-frame2.png

これで次のような画像になります。

図9. 同じ画像ですが、もう少し飾りを付けたもの
A picture of the each with a slightly more complicated border

最後に、さらにもう少し装飾を追加すると、望みの効果が得られます。

convert -mattecolor black -frame 5x5+2+2 beach.png beach-frame3.png

最後にこういう画像が出来上がります。

図10. 仕上がった枠取り
A picture of the beach with a finished frame

自分の画像に素敵な枠取りをする方法を探しているのでしたら、ちょっと時間をかけて、-frameコマンドの引数をいじってみる事をお勧めします。例えば、下記はオーストラリアのKing's Canyonにある岩の画像につけた面白い枠取りの例です。

他にはどんな枠取りがあるのか、convertmanpageを調べてみてください。

convert -mattecolor gray -frame 25x25+0+25 rock.png rock-frame1.png

convert -mattecolor gray -frame 25x25+25+0 rock.png rock-frame2.png

図11. 枠取りの例
A couple of rock pictures with nice frames

大量の画像を一度に処理する

前回の記事で、大量の画像を一度に変換するためのサンプル・コードをお見せしました。何人かの読者から指摘されたのですが、私がお見せしたコードは最良のものではありませんでした。

私がお見せしたコードは次の通りです。

リスト1. カレント・ディレクトリにある全JPEGファイルをサムネイル画像にする
for img in `ls *.jpg`
do
  convert -sample 25%x25% $img thumb-$img
done

気が付いてみると、これはbashでの方法としてはかなり雑で、ファイル名にある空白をあまり丁寧に扱いません(各単語が別々のファイル名として扱われてしまいます)。bashでこれを行うもっと良い方法は

リスト2. bashをうまく使ってカレント・ディレクトリにある全JPEGファイルをサムネイル画像にする
for img in *.jpg
do
  convert -sample 25%x25% $img thumb-$img
done

これでファイル名にある空白がもっと丁寧に扱われるようになります。

ところが、このどちらの手法もImageMagickを使えば必要なくなる事が分かります。単にmogrifyコマンドを使いさえすれば良いのです。mogrifyは(単一の画像にも使えるのですが)一連の画像を変換するのに使います。

上のコード断片は次のようになります。

mogrify -sample 25%x25% *.jpg

注意して欲しいのですが、これは元の画像を新しい画像で上書きしてしまいます。これはmogrifyの限界の一つで、出力ファイル名を規定するのが難しいのです。出力ファイル名を規定する唯一の方法は、出力画像のフォーマットを入力画像のフォーマットとは異なるものにすることです。これを行うと新しい画像の拡張子は変わります。例えば

mogrify -format png -sample 25%x25% *.jpg

このコマンドで、ファイル名の最後にあるjpgがpngで置き換えられ、画像フォーマットもそれに応じて変更された一連の出力ファイルが出力されます。

前に定義した変換はすべてmogrifyコマンドでも動作します。ですから元の画像が上書きされるのを気にしないのであれば、それも良い選択になります。上書きされるのを気にするのであれば、一時ディレクトリに元ファイルをコピーし、mogrifyしてからファイル名を変更します。・・・または相変わらずconvertとbashを使う、と言う選択肢もあります。


PDFの処理

今回の記事でも前回の記事でも、ここまでの例では各画像が独立な場合の単純な変換を説明しました。ImageMagickを使うと2つ以上の画像を一度に変換するという面白い事もできるので、これを説明しておこうと思います。

最も一般的な例はImageMagickによるPDFの処理です。一連の画像(1ページに1画像)をPDFとして受け取ったとしましょう。ImageMagickはこれらの画像を別々のファイルに抽出するのです。例えば、下記は私がlinux.conf.auに参加した時の画像をいくつか含んだPDF文書のスクリーン・ショットです。

図12. 大量の画像を含んだPDFの例
Some images in a PDF

友達の誰かが上のPDFを送ってきたとしましょう。あなたはこの画像をさらに処理するために抽出しようとします。

当然ながらconvertはPDF文書からこうした画像を抽出できるのです。

convert foo.pdf pages.png

このコマンドで目的を果たす事ができます。つまり、各ページを抽出して、それ自身をPNGファイルにできます。ところが名前の付け方に予期しない副作用があるのです。

リスト3. ファイル名をチェックアウトする
mikal@deathstar:~/foo$ convert foo.pdf pages.png
mikal@deathstar:~/foo$ ls pages*
pages.png.0  pages.png.1  pages.png.2  pages.png.3  pages.png.4
mikal@deathstar:~/foo$

このコマンドで2つ以上のPNGファイルを生成したので、そのファイル名には固有の番号が付加されています。これは、次にファイルの拡張子に基づいてファイル形式を想定するコードやスクリプトを使おうとする場合には、あまりうまく働きません。

convertは使いやすいユーティリティなので、ファイル名をもう少しうまい方法で規定できるのです。上のコマンドは、実際には次のようになっているべきなのです。

リスト4. PDF文書から(適切なファイル名を付けて)ページを抽出する
mikal@deathstar:~/foo$ convert foo.pdf pages-%03d.png
mikal@deathstar:~/foo$ ls pages*
pages-000.png  pages-001.png  pages-002.png  pages-003.png  pages-004.png
mikal@deathstar:~/foo$

%03dはprintf風の書式指定子です。この使い方で知っておく必要があるのは、%dが十進数を意味することと、画像の一連に0<数字>を挿入することで先頭のゼロ一式を詰め込むこともできるということだけです。この数字は表示される値が使用する総桁数を規定します。

テキストを含んだPDFのページも抽出できる事には注意してください。実際に下で行われているのは、ImageMagickがGhostscriptを使ってページを描画してから、指定した画像フォーマットに変換する操作なのです。ただし、OCR(optical character recognition)はありません。得られるのはビットマップです。

convertで画像ファイルをPDFに変換する事もできます。実際、上の例で使ったPDFは次のコマンドを使って作ったものです。

convert dsc* foo.pdf

単純に画像ファイルのリストをconvertに渡し、リストにある最後のファイル名が、画像ファイルをまとめるべきPDF文書の名前になるようにします。


ファイル当たり2つ以上の画像をサポートする他のフォーマット

ImageMagickと組み合わせて使うと2つ以上の画像を保存できるファイル・フォーマットとして他にも45のフォーマットがあります。完全なリストへのポインターは、この記事最後の参考文献にあります。

これらは全て、先に説明したPDFの例と同様に取り扱われます。中には非常に面白いものもあります。ポストスクリプト・ファイルのページを画像として抽出できれば非常に便利(例えば、公開した論文のサムネイルが自分のWebページにあることを考えてみてください)ですし、TIFF画像として受信した何ページものファックスの画像のどれにでも行けるとしたら、それも便利です。

MPEGムービーから一部の画像を抽出することもできるのですが、これについてはこの記事よりもずっと多くのページが必要になってしまいます。


まとめ

この記事では、前回の記事で説明したImageMagickに関する面白い手法を拡張してみました。説明の内容としては、画像(特に前回説明したサムネイルに関して)のコーナーに丸みをつけるにはどうするか、素敵な枠取りを付け加えるには、また一度に大量の画像を処理するにはどうするか、などです。最後は複数ページのフォーマットから画像を抽出するにはどうするか、また複数ページの新しい文書を作るにはどうすべきかについて説明しました。

もっと情報が必要な方は参考文献にある、ImageMagickのWebサイトを調べてみてください。また、もし質問がある場合には遠慮なく私にメールをお送り下さい。

読者の方々から色々な質問をいただいたおかげでこの記事を書く事ができました。ご協力ありがとうございます。また、質問にお答えするまでに長い間お待たせして申し訳ありませんでした。

参考文献

  • ImageMagickは89以上の主要フォーマットの画像を読み、書き、操作するツールやライブラリの集まりです。 ImageMagickのWebサイトは素晴らしい情報源で、ここからImageMagickのソースコードがダウンロードできます。 Command-line utilities ページにはconvert、mogrify、compositeその他compareやconjureのツールとそのオプションに関する情報があり、ImageMagickが認識するファイル・フォーマットの完全なリストも置かれています。
  • ImageMagick はまた、CやJavaからPerlやPHPに至るまで、お好みのプログラミング言語から呼び出す事もできます。詳しい情報についてはprogramming interfacesを調べてみてください。
  • GIMP (GNU Image Manipulation Program)は無料で配布されているソフトウェアで、画像の加工、合成や編集などに好適です。ライセンス条件をGNU General Public License (GPL)として提供されています。
  • コマンドラインからのグラフィックス操作」(developerWorks, 2003年7月)はこのシリーズ最初の記事で、ImageMagickを使ってサムネイルを作ったり、回転したり、面白い操作を加えたり、画像情報を決定したりする方法を説明しています。
  • libtiffによるグラフィックス・プログラミング」(developerWorks, 2002年3月)はTIFF画像に焦点を絞って、白黒画像の概念を説明しています。
  • libtiffによるグラフィックス・プログラミング: 第2回」(developerWorks, 2002年6月)ではカラーのTIFF画像について説明していますが、目的によってどんな圧縮方式が適切か、といった重要な話題についても説明しています。
  • Scalable Vector Graphics (SVG)はXMLアプリケーション言語で、アニメーションやスクリプト機能を含めた2Dベクター・グラフィックスを記述します。手始めとしてInteractive, dynamic Scalable Vector Graphicsがあります(developerWorks, 2002年2月)。
  • IBM Toolkit for MPEG-4は一式のJavaクラスとAPIで、再生サンプルやMPEG-4生成アプリケーションが含まれています。これはalphaWorksで最も人気のあるダウンロード項目の一つです。ご覧になれば何故か分かって頂けるでしょう!
  • VoiceXMLで、手に入れた画像に音声を追加することができます。手始めにVoice-Enabling Your Web Sites(developerWorks, 2001年11月)を読んでみてください。
  • developerWorks LinuxゾーンにはLinux開発者向けの資料が豊富に用意されています。
  • Developer BookstoreのLinuxセクションには幅広い話題の技術書が取り揃えてあります。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux
ArticleID=228573
ArticleTitle=コマンドラインからのグラフィックス操作 第2回
publish-date=03162004