しゃかまる

2013.04.24

ImageMagickを使ったPHPによる画像編集のTips

初めまして。開発本部に2月に入社した村上と申します。

最近、PHPで動的に画像編集することがあったのですが
なかなか面倒な上に情報が少なかったのでTipsとして書きたいと思います。
この記事では、画像の合成・回転・テキストの描画・テキストの回転について書きます。

導入

PHPへのImageMagickの導入についても書きたいのですが
長くなってしまいますので割愛します。すみません。
PHPのImageMagickはpeclのImagickというパッケージを使うことになりますので
peclからインストールしてください。

リファレンス

実際に私がコーディングしていた時はメソッドの引数の名前が書いているだけで
ほとんど書かれていないような状態だったのですが、見返してみると最近更新されたようで
メソッドの説明など充実していました。

( ^o^)<Imagickの記事を書くぞ
( ˘⊖˘) 。o(リファレンスが不親切だったからdisっちゃおうかな)
|PHP| ┗(☋` )┓
三 ( ◠‿◠ )☛ 更新したよ [Last updated: Fri, 19 Apr 2013]
▂▅▇█▓▒░(‘ω’)░▒▓█▇▅▂うわあああああああ

という流れでした。なぜ開発が終わった後にorz

ImageMagickの基本的な使い方

Imagickクラスのインスタンスを作るためには

と、コンストラクタに画像ファイルの引数を与えます。

この画像ファイルのパスが間違っていたり存在しないと、ImagickExceptionを吐きますので、try-catchしましょう。

画像の合成

画像の合成には ImagickのcompositeImageメソッドを使います。
当ブログの下と右にいる画像を使ってご説明します。判別のため、それぞれの画像の縁を赤と青で囲いました。

合成のコードは以下のようになります。

これを実行すると、画像が合成されてこんな風になります。

次に、画像を回転させてみましょう。

画像を回転

画像の回転には Imagickのrotateメソッドを使います。
ピーチクのアイコンを左に45度回転させました。

コードは以下です。

第1引数に背景色、第2引数に角度を指定します。
角度は負の値でも問題ありません。
背景色をnoneとすると、透過させることが出来ます。

実行結果はこのようになります。

次は、画像にテキストを加えてみましょう。

テキストを描画

テキストの描画は少々煩雑です。
ImagickPixel, ImagickDrawクラスを使います。
それぞれ、ImagickPixelException, ImagickDrawExceptionを吐くので、使う場合は注意が必要です。

実際にはこのようになります。

テキストの描画前にqueryFontMetricsで値を取っています。
これはテキストを描画した際の状態を取得するもので、描画した際の横幅や高さを取得出来ます。
var_dumpすると以下のような情報が取れます。

テキストを書き出す際にも注意が必要です。

テキストの描画位置はImagickとは異なり、指定した位置に文字の下端が来る位置に描画されます。
つまり、任意の位置から描画を開始させるには、queryFontMetricsで描画した際の文字の高さを取得して
その分高さをずらして配置する必要があります。
ここの例では文字の高さが 23pxなので、描画位置をずらしています。
実行結果は以下になります。上の方に青字で描画しました。

テキストを回転

テキストの回転はもっと厄介でした。
ImagickDrawにもrotateメソッドがあるので、これを使えばいいようにも思えますが
Imagickと同じノリで使うと罠にはまります。
リファレンスには

指定した回転を現在の座標空間に適用する

とあります。
Imagickは画像単体で回転させて任意の位置に設置できるのですが、ImagickDraw::rotateは
描画開始位置を中心として回転します。

書き出し位置をX軸に200pxとして45度回転すると、斜め方向に200px移動してしまいます。
厳密に描画位置を決めたい場合はこれだと制御が困難でした。

ということで実際に採った方法は以下です。

小さい透明画像をあらかじめ用意しておき、Imagickでインスタンスを作ります。
テキスト用のインスタンスを生成したら、メトリクスからテキストのwidth, heightを取得します。
テキスト背景画像の大きさをテキストの大きさに最適化し、テキストを描画します。
テキストを描画した後の背景画像をImagick::rotateを使って回転します。

上記の実行結果が以下になります。
テキストが回転していることが分かりますね。

ということでPHPによる画像処理でした。
Imagickはかなりのメソッドがあるのでもっといろんなことが出来そうですね。