イギリスの SF 作家 Arthur C. Clarke はかつて、「どのような技術であれ、非常に高度な技術は魔法と区別できない」と言っています。今日の高度な技術を実際に使用している人間としては、確かに私達のツールが時として魔法のように見えることを認めざるを得ません。例えば、皆さんがそれほど昔ではない別の時代から来た人であり、私達が最新の技術を使う様子を見ている、と想像してみてください。私達が友達や家族、ペット、職場、さらには私達自身の写真を撮り、画像を転送、処理し、最後に印刷する、という段階ごとに、次々と魔法を繰り出しているように見えるでしょう。
ImageMagick は、100 種類を超える多様なフォーマットのデジタル画像を作成、編集、合成、変換できるようにする一連のプログラムに付けられた総称的かつ華やかな名前です。このツール自体は個別のプログラムやライブラリーで構成されているため、ImageMagick を使用すれば、前述のような画像操作をするための選択肢が操作面でもプログラム面でも非常に広範なものになります。
この記事では主に、convert と display というコマンドライン・ユーティリティーの使い方に焦点を絞ります。ImageMagick は本格的なツール・スイートなので、この記事を読み終わる頃には、このツール・スイートに好印象を持つことになるでしょう。
広い意味で言えば、「エディター」と呼ばれるコンピューター・プログラムは特定のタイプのデジタル・データを容易に作成、変更、保存できるようにすることを目的に作られたプログラムです。デジタル・データのタイプが数多くあるのと同じように、エディターにも数多くのタイプがあります。文書やプログラム・コード、スクリプトを対象としたテキスト・エディターには、有名なものとして vi や Emacs があります。音声データを対象としたエディターには、Audacity や Wavosaur などがあります。ImageMagick はグラフィック画像の編集専用のエディターです。
他の多くの画像エディターと同様、ImageMagick は対話型の画像編集環境を提供しています。しかし ImageMagick は、多くの標準的なプログラミング言語で使用できる包括的な API (Application Programming Interface) も提供しています。ImageMagick のプログラマー・コミュニティーは数多くの便利なプログラムを提供しており、それらの中から選択して編集することで、皆さんの思いどおりの機能を実現することができます。
画像操作の機能を説明する場合には、言葉による説明よりも図を使った説明の方が適切です。そして ImageMagick の Web サイトでは、画像操作の各機能による効果が実際にどのようなものかを、豊富な図を使って説明しています。(画像操作の詳細については「参考文献」のリンクを参照)
一般的に使用されているグラフィック画像のフォーマットは 100 種類を超えています。そのため、既存の画像を簡単に編集できるように、ImageMagick には convert プログラムが用意されています。convert プログラムはあるフォーマットから別のフォーマットに変換するだけではなく、ImageMagick 独自の対話型エディターに最適な形式となるように画像を変換することもできます。
ImageMagick の強みの 1 つはスクリプト機能なので、カスタマイズしたスクリプトを作成することで、特殊なプロジェクトに容易に画像を組み込むことができます。一例として、見込み客の個人データ (名前、住所、電話番号等) に応じて、販促用パンフレットの一連の画像を自動的にカスタマイズすることができます。
この ImageMagick のエディター機能を使用した実際の例として、私の娘夫婦の猫 (ちなみに名前は Merlin です) の画像について検討してみましょう (図 1)。
図 1. 猫の Merlin
見栄えのよい見出しを画像に追加するために、以下のようなコマンドを使います。
$ convert bMerlin.jpg -font Ubuntu-Bold-Italic \ -pointsize 56 -fill blue -annotate +25+70 \ 'Merlin, the Wizard of Cats' NewMerlin.jpg |
Ubuntu-Bold-Italic フォントがないシステムの場合には、利用可能なフォントを以下のコマンドで一覧表示することができます。
$ convert -list font |
この画像の処理が終わると、図 2 の画像が表示されます。
図 2. キャプションを追加して修正された画像
これを見るとわかるように、ImageMagick で魔法をかけるのは決して難しくありません。単に練習して ImageMagick の使い方を理解すればよいのです。ImageMagick を作ったプログラマー達、いや魔法使い達は、このツールのための素晴らしいドキュメントを作成して Web サイトに公開しています。ぜひそのサイトを訪れ、この記事から学んだ内容の理解を深めてください。(「参考文献」を参照)
この強力なツールでプログラマーが利用できるライブラリーの選択肢は膨大な数になります。使い慣れたプログラミング言語と各言語用の単純な API
を使用することで、ImageMagick の強力さをプログラムに組み込むことができます。ImageMagick のコマンドをそのまま使用した単純な bash
スクリプトから、C や Perl といった言語の API 関数の呼び出しに至るまで、ImageMagick はそのプログラミング対応力の高さで、他のグラフィック操作ツールとの差別化を図っています。
対話型エディターを使用すると、1 つの画像を細かく調整することも、複数の画像全体に変更を加えることもできます。この対話型エディターを始めとする多様なエディターを活用できることが ImageMagick の価値を高めています。
デジタル画像のグラフィック・ファイル・フォーマットは 100 種類を超えています。ImageMagick では非常に多様な標準を扱うことができるため、複雑な処理も容易に行えるようになります。
ImageMagick は多種多様なオペレーティング・システムで動作します。完全に機能するバージョンが、Windows、UNIX と Linux、Mac OS X、Apple iOS それぞれに対して用意されています。この記事では Ubuntu Linux バージョンに焦点を絞ります。ソース・コード、またはお好みのシステムのバイナリー・バージョンをダウンロードする方法については、「参考文献」のリンクを参照してください。
多くのオープンソース・システムの場合と同様、プログラムを入手する際には最初に選択を迫られます。つまりソース・コードからコンパイルするのか、それとも各システム専用にコンパイル済みのバイナリー・バージョンをダウンロードするのかを選択する必要があります。どちらにも利点がありますが、私はソースからシステムをビルドする方法を選びます。
どのディストリビューションにも、ビルド済みのバイナリーを追加するための独自の方法があります。Debian Linux から派生したディストリビューション (Ubuntu など) に ImageMagick をインストールするためには、Synaptic Package Manager のような GUI ベースのパッケージ・マネージャーを使用するか、以下のようにコマンドラインで操作を行います。
$ sudo apt-get install imagemagick |
また、構成ファイルの場所の変更や独自のビルド設定など、好みに合わせて ImageMagick をカスタマイズすることもできます。そのためには、ImageMagick
をソースからビルドする際にコマンドラインのオプション・スイッチを使用します。これらのオプションを一覧表示するためには、以下のように configure コマンドを使用します。
$ ./configure --help |
これらのオプションの多くは、皆さんのマシンでビルドのトラブルが発生した時に役立ちます。
*nix ベースのコンピューターでオープンソースのプログラムをビルドする場合、そのほとんどにおいて 3 つのコマンドを使用しますが、ImageMagick も例外ではありません。標準的なコマンドは以下のとおりです。
$ ./configure- 構成スクリプトの目的は、次のステップのためのカスタムの Makefile を作成することです。構成スクリプトは一連のステップを整然と実行してマシンの構成を判断し、(必要なライブラリーなど) 何か重要なものが不足していること、あるいはすべてが順調で Makefile が正常に作成されたことをレポートします。
$ makemakeプログラムは、この前のステップで作成された Makefile を使用して、ImageMagick スイートを構成するすべてのプログラムをビルドし、また関連するドキュメントも作成します。$ sudo make install- この最後のコマンドにより、プログラム、ドキュメント、そして関連するデータ・ファイルが、それぞれの本来の場所にコピーされます (この場所はシステムのすべてのユーザーにとって当然と思われる場所です)。通常、それは /usr/local/bin ディレクトリーです。
ImageMagick は、画像を編集するための対話型プログラムが用意されているという点で他の画像エディターと似ています。ImageMagick を起動すると、メニュー方式の画像操作ツールを利用して画像を編集することができます。
display コマンドを使用すると ImageMagick の対話型エディターを起動することができます。この場合、ファイル名を関連付けて指定することも、ファイル名を指定せずに起動することもできます。このインターフェースは他の多くの描画型プログラムの場合と似ており、使い方は容易であり、メニューで操作することができます。
display コマンドを入力します。すると、図 3 のウィンドウが表示されるはずです。
図 3. ImageMagick のエディター・ウィンドウ
このウィンドウをクリックし、メニューから「File (ファイル)」 > 「New (新規)」の順にクリックすると、ビットマップ画像の作成を開始することができます。ビットマップ画像の作成では、まず画像の幾何形状を入力するように促され、続いて画像の背景色の入力を促されます。画像の幾何形状を入力する際、背景色にグラデーションを付けるように選択することもできます。
キャンバスが作成されると、描画ツールを使ってキャンバスに描くことができます。「Image Edit (画像の編集)」 > 「Draw (描画)」の順にクリックします。すると、モードが変更されて新しいメニューが表示され、キャンバスのカーソル機能が変更されます。この時点で、描画ツールを選択し、皆さんのアイデアをキャンバスに描きます。「Draw (描画)」機能を離れて「Color (着色)」機能によって画像の一部に色をつけたり、特殊なエフェクトを追加したり、その他さまざまな創造的作業をすることができます。
さまざまな方法で既存の画像を編集することができます。単純に display <画像ファイル名>
というコマンドを入力すると、先ほど説明した対話型エディターを使用することができますが、ImageMagick
スイートの他のツールを使って画像を操作することもできます。例えば convert プログラムを使用すると、ある画像ファイルを別の環境に適した他の一般的なグラフィック・ファイル・フォーマットに変換することができます。
この方法を理解するために、ここでは「cat party (猫パーティー)」への一連の招待状を生成するプログラムを使用します。このプログラムは bash スクリプトの形式にするので、まず xterm を起動し、以下のようにして最初のファイルを作成します。
$ touch catcards $ chmod a+x catcards |
スクリプト・ファイルを作成し、そのファイルを実行可能形式にしたら、次のステップとして、お気に入りのプログラム・エディター (vi や Emacs など) を開き、bash スクリプトで記述したリスト 1 のプログラム・コードを catcards ファイルに入力します。
リスト 1. 招待状を生成するための bash スクリプト
---
#!/bin/bash
# A "catcard" bash script for demonstrating ImageMagick
# and generating invitations to a "cat party."
# 20111115 by Bill Zimmerly.
# Find the "seq" command, to generate sequence numbers.
SEQ=`which seq`
# Create the guests file. Comment this
# out if "guests" is an external file.
# (Important Note: "cat" in this script
# has nothing to do with cats!)
cat > guests << EOF
Grandma
Aunt Linda
Uncle Dave
Aunt Rachael
Uncle Joe
Uncle Myk
EOF
# Read the guests into an array called "a."
# (Note: IFS is the field separator value,
# which in this case MUST be set for lines.)
old_IFS=$IFS
IFS=$'\n'
a=($(cat guests))
echo "Generating $((${#a[@]})) invitations to:"
# Generate the invitations.
for i in $($SEQ 0 $((${#a[@]} - 1)))
do
# Use base=1 for human counting and
# show it on the console.
j=i
((j += 1))
echo $j. ${a[$i]}
# Prepare the file name.
echo "Merlin"$j".jpg" > filename
# Prepare the invitational text.
echo ${a[$i]}", I love you and" > text1
echo "I want you to come to my" > text2
echo "cat party to scratch my belly." > text3
echo "Sincerely," > text4
echo "Merlin" > text5
# Use ImageMagick's "convert" command
# to generate a new card.
convert bMerlin.jpg \
-font Ubuntu-Bold-Italic \
-pointsize 24 -fill blue \
-annotate +25+40 $(cat text1) \
-annotate +25+70 $(cat text2) \
-annotate +25+100 $(cat text3) \
-annotate +25+130 $(cat text4) \
-annotate +25+160 $(cat text5) \
$(cat filename)
done
# Restore the field separator value and clean up
# temporary files.
IFS=$old_IFS
rm guests
rm filename
rm text1
rm text2
rm text3
rm text4
rm text5
exit 0
---
|
素材の画像として、猫の Merlin の画像 (図 1) を右クリックし、catcards スクリプトと同じディレクトリーに保存します。(この画像は catcards スクリプトのデータとして必要です。)
最後に、このスクリプトを実行し、生成されたファイルを一覧表示します (リスト 2)。
リスト 2. スクリプトを呼び出して招待状を生成する
$ ./catcards Generating 6 invitations to: 1. Grandma 2. Aunt Linda 3. Uncle Dave 4. Aunt Rachael 5. Uncle Joe 6. Uncle Myk $ ls Merlin* |
今やディレクトリーの中に新しい 6 つの画像があることに注意してください。今度は ImageMagick の display コマンドを使って各画像を表示してみると、いかに各画像が異なるかに気付くはずです。
$ display Merlin1.jpg
.
.
.
Etc.
|
例えば、図 4 は叔母の Rachael 用に生成された招待状の画像を示しています。
図 4. 叔母の Rachael を猫パーティーに招くための招待状
このプログラムは変更も容易であり、すべての顧客を対象に販売資料を作成することや、カスタマイズした画像を作成することもできます。
プログラマーは 2 つの方法で画像操作機能を組み込むことができます。1 つは C で MagickWand API を使用する方法、もう 1 つは MagickCore API を使用する方法です。
1 つの例として、ImageMagick を開発した人達は画像のコントラストを高めるためのサンプル・プログラムを作成しました (このプログラムの詳細については、「参考文献」のリンクを参照)。リスト 3 はそのコードを示しています。
リスト 3. 画像のコントラストを変更するための C プログラムの例
---
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <wand/MagickWand.h>
int main(int argc,char **argv)
{
#define QuantumScale ((MagickRealType) 1.0/(MagickRealType) QuantumRange)
#define SigmoidalContrast(x) \
(QuantumRange*(1.0/(1+exp(10.0*(0.5-QuantumScale*x)))-0.0066928509)*1.0092503)
#define ThrowWandException(wand) \
{ \
char \
*description; \
\
ExceptionType \
severity; \
\
description=MagickGetException(wand,&severity); \
(void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
description=(char *) MagickRelinquishMemory(description); \
exit(-1); \
}
MagickBooleanType
status;
MagickPixelPacket
pixel;
MagickWand
*contrast_wand,
*image_wand;
PixelIterator
*contrast_iterator,
*iterator;
PixelWand
**contrast_pixels,
**pixels;
register ssize_t
x;
size_t
width;
ssize_t
y;
if (argc != 3)
{
(void) fprintf(stdout,"Usage: %s image sigmoidal-image\n",argv[0]);
exit(0);
}
/*
Read an image.
*/
MagickWandGenesis();
image_wand=NewMagickWand();
status=MagickReadImage(image_wand,argv[1]);
if (status == MagickFalse)
ThrowWandException(image_wand);
contrast_wand=CloneMagickWand(image_wand);
/*
Sigmoidal non-linearity contrast control.
*/
iterator=NewPixelIterator(image_wand);
contrast_iterator=NewPixelIterator(contrast_wand);
if ((iterator == (PixelIterator *) NULL) ||
(contrast_iterator == (PixelIterator *) NULL))
ThrowWandException(image_wand);
for (y=0; y < (ssize_t) MagickGetImageHeight(image_wand); y++)
{
pixels=PixelGetNextIteratorRow(iterator,&width);
contrast_pixels=PixelGetNextIteratorRow(contrast_iterator,&width);
if ((pixels == (PixelWand **) NULL) ||
(contrast_pixels == (PixelWand **) NULL))
break;
for (x=0; x < (ssize_t) width; x++)
{
PixelGetMagickColor(pixels[x],&pixel);
pixel.red=SigmoidalContrast(pixel.red);
pixel.green=SigmoidalContrast(pixel.green);
pixel.blue=SigmoidalContrast(pixel.blue);
pixel.index=SigmoidalContrast(pixel.index);
PixelSetMagickColor(contrast_pixels[x],&pixel);
}
(void) PixelSyncIterator(contrast_iterator);
}
if (y < (ssize_t) MagickGetImageHeight(image_wand))
ThrowWandException(image_wand);
contrast_iterator=DestroyPixelIterator(contrast_iterator);
iterator=DestroyPixelIterator(iterator);
image_wand=DestroyMagickWand(image_wand);
/*
Write the image then destroy it.
*/
status=MagickWriteImages(contrast_wand,argv[2],MagickTrue);
if (status == MagickFalse)
ThrowWandException(image_wand);
contrast_wand=DestroyMagickWand(contrast_wand);
MagickWandTerminus();
return(0);
}
---
|
このソース・コードを contrast.c というファイルに保存すると、以下のコマンドを使用して contrast プログラムをビルドすることができます。
$ cc `MagickWand-config \
--cflags --cppflags` \
-O2 -o wand wand.c \
`MagickWand-config --ldflags --libs`
|
contrast プログラムがビルドされると、このプログラムを以下のように使用して Merlin の画像のコントラストを高めることができます。
$ ./contrast bMerlin.jpg MerlinX.jpg |
図 5 の画像を先ほどの Merlin の画像と比べてみてください。
図 5. contrast プログラムを実行した結果
画像処理ライブラリーとプログラムとの下位レベルのインターフェースが MagickCore API です。この API は主にシステム・プログラマーが使うためのものであり、環境の初期化、オブジェクトのインスタンス化、フーリエ変換の計算など、上位レベルでは通常見られない基本的な機能を備えています。
ImageMagick ライブラリーを使用したプロジェクトを配布する
ImageMagick は Apache 2.0 オープンソース・ライセンスの下で配布されており、ImageMagick を皆さんのプロジェクトに使用する場合、いくつか特定の要件があります。簡単に言えば、皆さんが配布するプロジェクトにこのライセンスの条文すべてを含め、ライセンスが Apache Software Foundation に帰属することを明確に記述する必要があります。Apache 2.0 ライセンスの完全な詳細については「参考文献」のリンクを参照してください。
画像エディターのなかで、ImageMagick スイートは画像ファイルを作成、編集するための強力なプログラマー・ツールキットとして際立つ存在です。先ほど bash
スクリプトや C コードの例で示したように、グラフィック関連のプロジェクトで魔法が必要な場合、この包括的な ImageMagick スイートが役に立ちます。
学ぶために
- ImageMagick について学んでください。
- ImageMagick による画像操作の例を見ながら、画像操作について学んでください。
- 皆さんの ImageMagick プロジェクトを配布する前に、必ず Apache 2.0 ライセンスの条項を理解してください。
- developerWorks の Open source ゾーンには、オープンソース・ツールの情報やオープンソース技術の使い方に関する情報が豊富に用意されています。
- 特定の技術リソースを見つけるための e-リファレンス・ライブラリー、Safari
bookstore を訪れてください。
- Twitter
で developerWorks をフォローしてください。
製品や技術を入手するために
- ImageMagick はバイナリーまたはソースとしてダウンロードで入手することができます。
- contrast.c プログラムは MagickWand C API を説明したページにあります。
- 皆さんの次のオープンソース開発プロジェクトを IBM ソフトウェアの試用版を使用して革新してください。ダウンロード、あるいは DVD で入手することができます。
- SourceForge で Audacity
について学び、また Audacity をダウンロードしてください。
議論するために
- developerWorks ブログから developerWorks コミュニティーに加わってください。
