うかつに ImageMagick に -define jpeg:size オプションをつけてはいけない

ImageMagick 遅い」などでググると下記ブログが上位に出てくる。

本当は速いImageMagick: サムネイル画像生成を10倍速くする方法
http://blog.mirakui.com/entry/20110123/1295795409

この記事内で、-define jpeg:size を指定することで 10 倍速くなるという話が出ているが、ここには落とし穴があるので注意。
それは、-define jpeg:size オプションが良い効果を発揮するには、変換元の画像サイズが十分に大きく、変換後の画像サイズが十分に小さくなければならないということ。


例えば 4000x4000 の JPEG を 200x200 にリサイズするというようなシーンなら -define jpeg:size オプションは絶大な効果を発揮する。しかし、4000x4000 を 2000x2000 にリサイズすると、オプション無しの時に比べて 3 倍近くメモリを消費するという挙動になる。時間的な面でもほぼ 3 倍程度時間がかかるので、逆効果になってしまう。

下記に、元画像のサイズ1辺を X 軸、変換後のサイズ1辺を Y 軸として、Z軸にメモリ使用量をプロットしたグラフを記載する。

f:id:shawshank99:20141126110843p:plain

赤い面が上にある箇所は -define jpeg:size オプション無しのほうがメモリを消費していることを表しており、青い面が上にある箇所は、オプション有りのほうがメモリを消費していることを表す。
見ての通り、元画像サイズが大きく、変換後のサイズも大きい場合には、-define jpeg:size オプションが逆効果になっている。
特に、-define jpeg:size オプション有りのものは、元画像サイズの 1/3 程度を超えると急激にメモリ消費量があがる。何らかのしきい値ImageMagick 内に存在しているように見える。

上記グラフはメモリ使用量に着目したグラフだが、悪いことに変換にかかった時間に着目しても同等の結果が得られる。
f:id:shawshank99:20141126110859p:plain


メモリを消費しても変換速度が速かったり、あるいはその逆なら、その特性を利用してサービスに適用することもできるが、メモリ,時間ともに悪い方に流れるのでイマイチなのである。

結論

結論としては、-define jpeg:size オプションは有効なシーンはあるものの、逆に悪化するシーンも多い。
画像変換をサービスとして提供し、ユーザーの任意サイズでリサイズ可能といったようなサービスの場合、-define jpeg:size オプションはトータルで見るとサービス劣化につながる可能性があるので、事前によく特性を調べて効果を測定するべきである。