ImageMagickを使えばさまざまな画像加工が簡単に出来てしまうのは有名ですよね。
ImageMagickは各言語で使えるライブラリが用意されています。今回はPHPのPECL::imagickです。
きっかけ
SPAM記録をTwitterでやりたい!
↓
文字でtweetすると厄介
↓
なら画像にしよう
↓
何使うの?
↓
やっぱImageMagickでしょ!
インストールしてみる
→なぜか動かない
いきなり本番環境にインストールをそこら辺に転がってる情報たよりにしようとした自分はバカだった。
# yum install ImageMagick
...
# pecl install imagick
...
# vim /etc/php.ini
...
一見インストール出来たかのようだったが何故かsetImageFormat
するだけでエラーがthrowされた。(違ったかも。セグメンテーション違反とか言われた覚えもある。)
自分でビルドもしてみたけどダメだった。
よくわからないままテスト環境で試行錯誤した結果、ある単純な解決方法にたどり着いた。
rpmリポジトリから普通にいけるじゃん
remi
にあったImageMagick-last
とphp-pecl-imagick
をインストールしてみたところ何の問題もなくImagickが使えた。なおPHPのバージョンごとに用意されているリポジトリからどうぞ。
# yum install --enablerepo remi,remi-php56 ImageMagick-late php-pecl-imagick
もしかしてImageMagick-lastはいらなかったのかもしれない。
とりあえず動作確認してみよう
動作確認の方法はいくらでもあるだろうけど今回特に必要としているのは画像への文字入れ
とりあえずphp.netのサンプルコードを借りて$_SERVER変数の中身を画像内に入れてブラウザに返してみる、ということをやってみよう。
<?
try{
$image = new Imagick();
$image->newImage(1300,800,new ImagickPixel('gray'));
$draw = new ImagickDraw();
$draw-> setFillColor(new ImagickPixel('blue'));
$draw->setFontSize(20);
$text = "";
foreach($_SERVER as $key => $val ):
$text.= "[{$key}] => {$val}\n";
endforeach;
$image->annotateImage($draw,10,30,0,$text);
$image->setImageFormat('png');
header('Content-type: image/png');
echo $image;
}catch(Exception $e){
header('Content-type:text/plane');
echo $e->getMessage();
var_dump($e);
}
WebPを試してみる
さて、ImageMagickは2011年ごろからWebPも扱えるようになっているらしい。WebPと言えばGoogleの開発する高圧縮な画像コーデック。
対応ブラウザがChromium系のみだったりと使いにくいのは確かだが、Googleの一部ページ内画像やChromeの帯域節約Proxyなんかでも利用されている。ちなみにChromeのような対応ブラウザはリクエストヘッダにContent-type: image/webp,*/*
を含め、サーバー側でそれに応じてwebpを返しているみたい。
このimagickでもwebpが使える。14~15行目を
$image->setImageFormat('webp');
header('Content-type: image/webp');
にするだけ。
15行目を
header('Content-type: */*');
みたいにテキトーな値にしておいてもChromeの開発者ツールにwebpと表示されていることが確認できる。
ところでこのWebP画像、明らかに非可逆圧縮されてるんだけどlosslessオプションはImagickではどうすればいいんだ…