ImageMagick vs GD - PHPでサムネイルを作る
画像のアップローダーを作っていて、その一環で UP された画像から携帯サイト向けのサムネイルと言うか、小さな画像を作る仕組みを考えました。
で、PHP だと GD と言う標準の画像処理ライブラリがあるので、最初はそれを使って処理しようと思ったんですが、いまいち画像が粗い。。。
クオリティーを上げる事も出来ますが、そうすると結局ファイルサイズが大きくなってしまう。
色々見てみると ImageMagick を使った方が画像的には綺麗な物が出来上がるようでしたので、GD と比べてどうなのか色々と試してみました。
結論から言うと、ImageMagick の方が綺麗に仕上がりますし、簡単に使えます。
そして、PHP から使うなら PHP のモジュールを使うより、shell_exec() を使って convert コマンドを直接読んだ方が圧倒的に楽でした。
一応今回の目的としては、画像が呼び出された時にリサイズして出力するのではなくて、アップロード時点でファイルをリサイズ・圧縮して保存する感じの使い方を想定してます。
まず、GD を使った場合のソースです。
$file_path = '/path/to/img.jpg';
$out_file_path = '/path/to/new_img.jpg';
$new_width = 200;
$img = ImageCreateFromJPEG($file_path); // JPEG
//$img = ImageCreateFromGIF($file_path); // GIF
//$img = ImageCreateFromPNG($file_path); // PNG
$width = ImageSX($img); // 幅(px)
$height = ImageSY($img); // 高さ(px)
$rate = $new_width / $width; // 圧縮比
$new_height = $rate * $height;
$new_img = ImageCreateTrueColor($new_width, $new_height);
//ImageCopyResized($new_img,$img,0,0,0,0,$new_width,$new_height,$width,$height);
ImageCopyResampled($new_img,$img,0,0,0,0,$new_width,$new_height,$width,$height);
ImageJPEG($new_img, $out_file_path); // JPEG
//ImageGIF($new_img, $out_file_path); // GIF
//ImagePNG($new_img, $file_path); // PNG
JPEG/GIF/PNGでそれぞれ関数が違うので、適当に組み合わせて使います。
サイズ変更に使える関数は ImageCopyResized と ImageCopyResampled がありますが、試した限りでは ImageCopyResampled の方が綺麗です。
と言うか、ImageCopyResized はクオリティー的に使えない。
ImageCopyResized
ImageCopyResampled
次は ImageMagick を使った場合。
まずは、PHP のモジュールを使った場合の例です。
$Imagick = new Imagick($file_path);
$Imagick->thumbnailimage($new_width, 0);
$Imagick->writeImage($out_file_path);
$Imagick->destroy();
入力・出力ファイル名や、サイズ指定は省略してますけど、これだけです。
超簡単。
ファイルタイプは自動で認識するので、特に意識せずに使えます。
例えば JPEG を読み込ませて、出力ファイル名を xxx.gif とかにすれば勝手に GIF に変換してくれます。
ただ、JPEG の場合、上記の指定だけだとクオリティーが元の画像のクオリティーと同じになってしまい、サンプルの様にデジカメで撮った画像をそのまま流すと JPEG のクオリティーが 98 とかで出てきてしまい、ファイルサイズがでかくなってしまいます。
Imagick クラスはいわゆるオブジェクト指向っぽい書き方なので、setCompressionQuality とかで指定してあげれば良いんだと思うのですが、その他にも PHP のモジュールだといちいち指定するのが面倒です。
なので、コマンドでやる方法を試してみました。
コマンドを shell_exec で呼ぶ場合の例です。
$cmd = 'convert ' . $file_path . ' -thumbnail ' . $new_width . ' -quality 75 ' . $out_file_path;
shell_exec($cmd);
これだけです。
上記の場合、JPEG の場合にはクオリティーを 75 にした画像を出力してくれます。
quality オプションを省略した場合には、入力した JPEG の画質が引き継がれるみたいです。
quality 75
quality 指定無し
$cmd の部分はシェルで ImageMagick を使う場合と同じです。
SSH でサーバーにログインできるのであれば、いちいちソース書いて UP してとかやらなくても、コマンドたたいてテスト出来るので、その意味でも楽だと思います。
convert は ImageMagick をシェルから使う際のコマンドですが、これだけでもかなりの事が出来ます。
convert のオプションの説明もなかなか見つからなかったのですが、こちらページが参考になると思います。
ちなみに、convert を使う場合も、ファイルタイプは自動で判別してくれて、入力と出力でタイプを変えた場合には勝手に変換して出力してくれます。
では今回作成したファイルを並べてみます。
GD ImageCopyResized
GD ImageCopyResampled
ImageMagick (convert quality 75)
ImageMagick (convert quality 指定無し)
ImageMagick (PHP)
こうして見ると ImageMagick を使った物の方が綺麗だと思いますがどうでしょうか?
当然、quality 指定をしていない Imagick と convert のサンプルが一番綺麗ですが、クオリティー 75でも十分だと思います。
ちなみにファイルサイズ的には
と言う感じです。
コメント