PHPでImageMagickでも

PHPで画像処理にはGDとImageMagickが主流でしょう
GDは簡単で、速度もそこそこ良い、リサイズした時の画質は微妙
Imagickはフォトショ並の画像処理できる、速度はGDに劣る、ドキュメントは不足

まあImageMagick、ジョブキューで使えば動的なGifアバター作成処理とかには最適だと思う(つかそう使ってる)

簡単な合成処理などはGDでサクッとやって、その他の画像処理とかGifアニメ作成はImageMagickで非同期的にやるみたいな

ところでImageMagickPHPの拡張モジュール使用するがドキュメントがほとんどないので少し戸惑う

ImageMagickのメモでも起こしておこう

ImageMagickは本体とPHP拡張モジュールをインストールする必要がある

インストール

本体はMacPorts等でパッケージあるからインストール

sudo port install ImageMagick
追加2012年11月7日

LZW有効にするためには

sudo port edit ImageMagick

でconfigure.argsに--enable-lzwを追加して
インストールし直す


ビルド終わったら拡張モジュールをインストール
pecl install imagickでもいけるが、MAMPで開発してるのでMAMPで使えるようにしたいのでソースコードビルドする

curl -O http://pecl.php.net/get/imagick-2.3.0.tgz
tar zxvf imagick-2.3.0.tgz
cd imagick-2.3.0
which php #=> /Application/MAMP/bin/php/php5.3*/bin/phpにパスが通っていることを確認
phpize
ln -s /Developer/SDKs/MacOSX10.6.sdk/usr/include /Appcation/MAMP/bin/php/php5.3.*/include
./configure --with-imagick=/opt/local
make
make install
echo "extension=imagick.so" >> /Application/MAMP/bin/php/php5.3.*/conf/php.ini

phpinfoにimagickがあればインストール成功
と思ったらない
php_error.logに以下のログが・・・

PHP Warning:  PHP Startup: Unable to load dynamic library '/Applications/MAMP/bin/php/php5.3.6/lib/php/extensions/no-debug-non-zts-20090626/imagick.so' - dlopen(/Applications/MAMP/bin/php/php5.3.6/lib/php/extensions/no-debug-non-zts-20090626/imagick.so, 9): Library not loaded: /opt/local/lib/libjpeg.8.dylib
  Referenced from: /Applications/MAMP/bin/php/php5.3.6/lib/php/extensions/no-debug-non-zts-20090626/imagick.so
  Reason: Incompatible library version: imagick.so requires version 13.0.0 or later, but libjpeg.8.dylib provides version 12.0.0 in Unknown on line 0

よくわからんが/Applications/MAMP/Library/bin/envvarsの以下のラインをコメントアウトしたらいいらしい

#DYLD_LIBRARY_PATH="/Applications/MAMP/Library/lib:$DYLD_LIBRARY_PATH"
#export DYLD_LIBRARY_PATH

これでおk

Imagickクラス

phpではImagickクラスを主に使用する
Imagickオブジェクトはイテレータの役割もこなす。(画像シーケンスと呼ぶ)
例えば、

$imagick = new Imagick("image.jpg");

として得られた$imagickオブジェクトは、画像シーケンスの一覧に"image.jpg"の画像データとしてのImagickオブジェクトが入れ子として入っているオブジェクトになる

$imagick2 = new Imagick("image2.jpg");
$imagick->addImage($imagick2);

として画像シーケンスにImagickオブジェクトを追加できる

$array = array("image.jpg", "image2.jpg");
$imagick = new Imagick($array);

また配列を引数とすると複数の画像の入ったImagickオブジェクトを作成できる。

サムネイル画像はthumbnailImageメソッドを使う
画像の表示はechoでおk(__toString)

$imagick->rewind(); // 画像シーケンスを最初に戻す。
$imagick->thumbnailImage(100,100);
$imagick->next();
header('Content-type: image/jpeg');
echo $imagick;

このようにすると2枚目の画像はサムネイル処理されていない事がわかる
画像処理は画像シーケンス上の現在のポインタ上の画像に対して行われる
ImagickはIteratorを実装してるのでforeachでイテレーションできる

foreach ($imagick as $im) {
    $im->thumbnailImage(100,100);
    $filename = $im->getImageFileName();
    $im->writeImage($filename."_new");
}

このように複数画像に同じ画像処理をすることができる
ざっくりいうとメソッド名にImage(not 複数形)が入ってるものは現在のポインタ上の画像に対するもののようだ

GIFアニメ

画像シーケンス上からGIFアニメを作る事ができる
writeImagesメソッドを使用する

$imagick->setFormat('gif');
foreach($imagick as $im) {
    $im->setImageFormat('gif');
    $im->setImageDelay(100); // 次の画像までの遅延
    $im->setImageDispose(1); // 画像の配置方法(背景色で一旦塗りつぶしてからか等)
    $im->setImageIterations(0); // ループ回数(0ならば無限)
}
header("Content-type: image/gif");
$imagick->writeImages("/tmp/asdf", true);
echo file_get_contents("/tmp/asdf");
unlink("/tmp/asdf");

大分遅い・・・