本当は速いImageMagick: サムネイル画像生成を10倍速くする方法


 ImageMagick  Imlib2 使
Imlib2 Imlib2ImageMagick3 - Imlib2  ImageMagick 3
 ImageMagick  Imlib2 使 Imlib2 2004Linux ImageMagick  Imlib2 

 ImageMagick 調  Imlib2 

いつもの convert に「-define jpeg:size=...」をつけるだけで10倍速くなる


2


1:  JPEG 

2: px


 4288x2848JPG(4.8MB)180x120px
 ImageMagick  convert 使
convert -resize 180x120 src.jpg dst.jpg


convert -define jpeg:size=180x120 -resize 180x120 src.jpg dst.jpg

*1

ベンチマーク

4288x2848のJPG画像(4.8MB)から180x120pxのサムネイル画像を以下の条件でそれぞれ10回ずつ生成し、変換にかかる時間を比較しました。

  1. ImageMagick での普通のリサイズ(縮小アルゴリズムはデフォルトのLanczos)
  2. ImageMagick で -define jpeg:size オプションを付けた場合のリサイズ(同様にLanczos)
  3. Imlib2 (imlib2-ruby) でリサイズ

ベンチマークのコードはこちら(gist: 488401)
結果は以下のとおりです。*2

条件 1枚あたりの平均変換時間(sec) 変換結果(quality=90)
1. ImageMagick(jpeg:size なし) 2.735397
2. ImageMagick(jpeg:size あり) 0.275900
3. Imlib2 0.832415

ImageMagick  jpeg:size 10Imlib2 3

jpeg:size 


なんで速くなるのか

なぜ jpeg:size で画像の大きさを指定しただけで、これほどまでに JPEG の縮小が速くなったのかを説明します。
そもそもこのオプションはなんなのかというと、公式ドキュメントに以下のような記述があります。

(以下、Common Formats -- IM v6 Examplesより意訳)

-define jpeg:size={width}x{height}

JPEGライブラリに、JPEGファイルの読み込みのヒントを与えます。このとき、作成される画像は、少なくともこの width x height より大きな画像になります。
もし入力画像が巨大なら、このヒントを与えることで、ImageMagickは小さな画像として開くため、画像読み込み時のメモリを大幅に節約でき、演算を劇的に高速化できるでしょう。
このオプションはあくまでヒントでしかなく、実際にその大きさの画像を得ることができるわけではないという点を忘れないでください。このヒントで指定したサイズに近い、かつそれ以上の大きさの画像を得ることになります。


調
4288x2848 JPEG 180x120 使
convert -define jpeg:size=180x120 -resize 180x120 src.jpg dst.jpg




(一)ImageMagick-define jpeg:size  180x120  src.jpg 

(二)ImageMagick src.jpg  4288x2848 

(三)ImageMagick 1/2(2144x1424)1/4(1608x1068)1/8(536x356) 180x120  180x120 1/8

(四)ImageMagick src.jpg 536x356

(五)ImageMagick src.jpg  536x356  180x120  dst.jpg 



f:id:mirakui:20110123181251p:image ImageMagick  -define jpeg:size={width}x{height}  1/21/41/8 JPEGJPEG8x816x16pxImageMagickJPEGlibjpeg1/21/41/8

ImageMagick ImageMagick Lanczos Imlib2 

convert -debug
 -define jpeg:size=180x120 
$ convert -debug Coder -log %e -resize 180x120 src.jpg dst.jpg
Profile: exif, 45952 bytes
Profile: xmp, 5079 bytes
Profile: iptc, 76 bytes
Interlace: nonprogressive
Data precision: 8
Geometry: 4288x2848
   :

Geometry  4288x2848  src.jpg  4288x2848 
 -define jpeg:size=180x120 
$ convert -debug Coder -log %e -define jpeg:size=180x120 -resize 180x120 src.jpg dst.jpg
Profile: exif, 45952 bytes
Profile: xmp, 5079 bytes
Profile: iptc, 76 bytes
Scale factor: 23.733333333333334281
Interlace: nonprogressive
Data precision: 8
Geometry: 536x356
   :

 Geometry  536x356  src.jpg  1/8  536x356 

まとめ

今回は、 ImageMagick で、JPEG画像の縮小を通常の10倍速くする方法を紹介しました。使えるシーンではどんどん -define jpeg:size をつけてみましょう。

 ImageMagick


 -define jpeg:size  ImageMagick-6.5.x 使-size使

おまけ: MagickWand では?

convert コマンドのオプションは -define jpeg:size=... ですが、同様の効果を MagickWand から得るためには、 MagickReadImage等 の前に

MagickSetOption(wand, "jpeg:size", "180x120");

を呼べばOKです。

おまけ: GraphicsMagick はどうなの?


ImageMagick ImageMagick  GraphicsMagick  ImageMagick 使

*1:ImageMagick-6.4.9 かそれ以前のバージョンでは、 -define jpeg:size=... でなく -size=... とします

*2:前回の記事よりCPUが貧弱な MacBook Air 11inch で計測しているのでやや遅めです