PHP GD の imagescale はそもそもアルゴリズム切り替え無効化されてる
試しに imagescale の第4引数の mode を切り替えて画像をリサイズしてみたのですが、
$modeList = array(IMG_NEAREST_NEIGHBOUR, IMG_BILINEAR_FIXED, IMG_BICUBIC, IMG_BICUBIC_FIXED); <略> foreach ($modeList as $mode) { echo "mode:$mode\n"; $im_out = imagescale($im_in, 256, 192, $mode); imagepng($im_out, $arg.'-'.$mode.'.png'); }
全ての mode で完全一致の画像が生成されました。('A`)
コードを見てみましょう
ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd); im_scaled = gdImageScale(im, new_width, new_height); goto finish; switch (method) { case GD_NEAREST_NEIGHBOUR: ...<略> } finish: if (im_scaled == NULL) { RETURN_FALSE; } else { ZEND_REGISTER_RESOURCE(return_value, im_scaled, le_gd); }
(ノ ̄皿 ̄)ノなんじゃこりゃぁ!┫:・’.::
無効化されてるっす。。
無理矢理有効化
ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd); // im_scaled = gdImageScale(im, new_width, new_height); // goto finish; switch (method) { case GD_NEAREST_NEIGHBOUR: ...<略> //finish:
これで、それっぽく動きました。
NEAREST_NEIGHBOUR | BILINEAR_FIXED | BICUBIC |
一見、BILINEAR がギザギザなくて綺麗に見えますが、例えば髪の毛の光沢を見ると元の絵より薄くなっていたり再現度がいまいちに見えます。
この辺は好みなのかな…
追記 (2014/02/03)
Area Average は別名、面積積分法というそうですが、以下のページを見る限り良さそうです。
ImageMagick には有名なアルゴリズムは大抵実装されてるので、そっち参照しようとしたけど含まれてないようで、試しにフィルタを実装してみようかな。