Making Thumbnails with RMagick
開始日 | 2007年02月01日 |
最終更新日 | 2009年06月03日 |
はじめに
Polaroid Effectが好評なので、調子に乗って別のページも翻訳し始めました。
原著
「Making Thumbnails with RMagick」
http://rmagick.rubyforge.org/resizing-methods.html
http://rmagick.rubyforge.org/resizing-methods.html
注意
- もともと個人利用を目的として日本語化したために、けっこう意訳している部分があります。「意味分からないよ」とか「おかしいんじゃない?」とかいうのがあれば、オリジナルを参照するか、コメントで質問してください(がんばって調べます)。
更新履歴
- 2007/2/1 作成開始
訳文
もしRMagickを使ったJPEG画像のサムネイル作成に対して、その遅さ(*1)が気になるのであれば、resizeメソッドではなくthumbnailメソッドの使用を検討した方がいい。
thumbnailメソッドはデフォルト引数のままであればresizeメソッドよりも速く、同じくらい魅力的な品質で結果を生成してくれるからだ。スピードの違いはリサイズ後のイメージが小さい(<1/10)ほど顕著に現れる。RMagickをImageMagick 6.2.6(*2)と一緒に使っているならば、これは良い選択肢だと思わないか?
thumbnailメソッドはデフォルト引数のままであればresizeメソッドよりも速く、同じくらい魅力的な品質で結果を生成してくれるからだ。スピードの違いはリサイズ後のイメージが小さい(<1/10)ほど顕著に現れる。RMagickをImageMagick 6.2.6(*2)と一緒に使っているならば、これは良い選択肢だと思わないか?
以下の内容を読んで、私がなぜこのような結論に至ったかを見てほしい。
RMagickでサムネイルを作るには
RMagickは、ImageMagickまたはGraphicsMagickライブラリのRubyバインディングだ。ImageMagick/GraphicsMagick双方のライブラリは画像リサイズ用の同じAPI一式を提供していて、RMagickではMagick::Imageクラスのresize、sample、scale、そしてthumbnailメソッドでこれらAPIをラップしている。
Christy(ImageMagickのチーフアーキテクトだ)はこれら4つのメソッドの違いを次のように説明している:
Christy(ImageMagickのチーフアーキテクトだ)はこれら4つのメソッドの違いを次のように説明している:
各メソッドの特徴(*3)
sample | 範囲内の中央ピクセルの情報だけを使ってリサイズする(つまり、画像中に無い色は生成されない)。resizeをPointFilterで使用したときと同じ。 |
scale | sampleに似ているが、浮動小数点によるサンプリングを実施し、周囲のピクセル情報も代表色に取り入れている。 |
thumbnail | 範囲内のピクセルを5点サンプリングし、その情報を元に代表色を決定・リサイズする。resizeメソッドで画像を1/5のサイズに縮小するときと同じ。プロファイルやコメント情報はstripされる。 |
resize | まぁ、あれだ。何でもありのメソッドだ。使用するフィルタを選んだり、ぼかしたりシャープにしたりもできる。フィルタは縮小時にはLanczosFilter、拡大時はMitchellFilterをデフォルトで使用する。代表色を作るとき、実は隣接ピクセルのアルファチャネル情報も考慮している。透明度の低いピクセルは高いピクセルよりも重みを多く持つ。 |
各手法のベンチマーク結果
私はRubyのベンチマーク用モジュールを使って、上で挙げた各メソッドのデータ生成までに要する時間を計測した。
テスト仕様は以下のとおり:
テスト仕様は以下のとおり:
- sample,scale,thumbnail,resizeの4種類を使用
- resizeは15種類のフィルタそれぞれで計測
- 2272x1704の写真(JPEG形式)を使用
- リサイズ後のサイズを200x150,300x225,400x300の3種類で計測
その結果はこの図のとおり。上がImageMagickを使用した結果で、下はGraphicsMagickの結果だ。両方のグラフは画像を200x150に縮小したときの負荷の大きさでソートしてある。
どのメソッドがベターなのか
さて、ベンチマーク結果を眺めてみよう。
まず、ImageMagickと、ImageMagickからブランチしたGraphicMagickとの間では明らかに値が異なっていることが分かる。GraphicMagickがどの方法でも一定のパフォーマンスを維持している一方で、ImageMagickはアルゴリズム(フィルタ)間のばらつきが大きい。どうもImageMagickでは、一部のアルゴリズムのパフォーマンスを得るために他のパフォーマンスを犠牲にしているようだ。
また、thumbnail以外のメソッドは作成する画像のサイズが大きくなるにしたがってCPU時間も微増していることも見てとれる。thumbnailメソッドだけはサイズが大きくなると途端に重くなっている。
また、thumbnail以外のメソッドは作成する画像のサイズが大きくなるにしたがってCPU時間も微増していることも見てとれる。thumbnailメソッドだけはサイズが大きくなると途端に重くなっている。
ちょっと待ってくれ、このthumbnailの結果に注目してくれないか。ImageMagick/GraphicsMagickに関係なく、生成後の画像サイズが小さいほど劇的に速くなっていることが分かるかい?これは上で説明した理屈と一致しているわけなんだけど、400x300という一番大きなサイズ(この大きさをもはや「サムネイル」と呼ぶかどうかは疑問だが(*4))のときでさえ、resizeをデフォルトのLanczosFilterで使用したときよりも速く出来ている。
「サムネイルの見栄えなんてどうだっていいよ、でも作成に時間がかかるなんてアリエナイ」なんて思っているなら、そりゃあsampleをずっと使っていればいい。どんな場合でも一瞬でサムネイルを作ってくれるからね。でも本当はノイジーでモザイクがかったような画像は嫌いなんじゃないか?
見栄えもソコソコ、スピードもソレナリな方法で、どれにすればいいか迷っているんだったらこちらの画像一覧を見てほしい。少しは参考になるだろう。
見栄えもソコソコ、スピードもソレナリな方法で、どれにすればいいか迷っているんだったらこちらの画像一覧を見てほしい。少しは参考になるだろう。
注意: |
紹介している画像はImageMagick6.2.6上で作成した。別バージョンやGraphicMagickを使っている人とは結果が違うかもしれないので、気をつけてほしい。 |
だけど簡単さと(ライブラリ間の)バラツキの無さを考えると、thumbnailは外せない。フィルターの選別に迷うこともないし、ImageMagickとGraphicsMagickとで同じようなパフォーマンスを持っているし、速いし、なかなかのサムネイルを作り出してくれる。
scaleメソッドはthumbnailと同じようなパフォーマンスを得られるし、画像サイズが大きいときはthumbnailよりも速い。でも出来上がる画像は、(私の見る限りでは)ちょっとシャープさに欠けるかな。
ちなみにImageMagick 6.2.6上では、resize+PointFilterはthumbnailによく似た画像を作り出し、thumbnailよりも速い。まぁ、人によってはこれでもいいかもしれない。
scaleメソッドはthumbnailと同じようなパフォーマンスを得られるし、画像サイズが大きいときはthumbnailよりも速い。でも出来上がる画像は、(私の見る限りでは)ちょっとシャープさに欠けるかな。
ちなみにImageMagick 6.2.6上では、resize+PointFilterはthumbnailによく似た画像を作り出し、thumbnailよりも速い。まぁ、人によってはこれでもいいかもしれない。
そうだ、thumbnail以外の方法を使った場合、出来上がったサムネイルからプロファイルやコメント情報をstripすることを忘れないでくれ。
巨大なJPEGファイルをサムネイル化するときのTips
サムネイル化したい画像が巨大ファイルサイズのJPEGデータだった場合、全データの読み込み&画像処理よりもっと良い方法がある。
それはImage::Infoの属性self.sizeを指定してファイルを読むことだ。求めているサムネイルサイズのちょうど2倍のサイズを指定してから読み込むと、ImageMagickのJPEGライブラリはファイルのデータ全部を読み込まず、必要な量だけを読み込んでくれるというわけだ。その後、適度に小さくなって読み込まれた画像を使ってサムネイル化する。
大きなファイルの読み込みはメモリを圧迫して無駄も多いので、ぜひ活用してほしい。
それはImage::Infoの属性self.sizeを指定してファイルを読むことだ。求めているサムネイルサイズのちょうど2倍のサイズを指定してから読み込むと、ImageMagickのJPEGライブラリはファイルのデータ全部を読み込まず、必要な量だけを読み込んでくれるというわけだ。その後、適度に小さくなって読み込まれた画像を使ってサムネイル化する。
大きなファイルの読み込みはメモリを圧迫して無駄も多いので、ぜひ活用してほしい。
詳細な説明は、AnthonyのExcelletなサイトにある「Reading JPEG Image」の項に載っているから、こちらも参照してくれ。
(このTipを提供してくれたAnthony Thyssonに感謝!)
(このTipを提供してくれたAnthony Thyssonに感謝!)
テスト構成
このベンチマークテストは以下の環境で実施した。
- Intel Pentium III(933MHz) 512MB RAM
- Mandriva2006
- Ruby 1.8.4
- RMagick 1.10.0
- ImageMagick 6.2.6 / GraphicMagick 1.1.7
ImageMagickとGraphicMagickはどちらも-O3を付けてコンパイルした。
ちなみにグラフ作成にはOpenOffice 1.1.5を使用している。
ちなみにグラフ作成にはOpenOffice 1.1.5を使用している。
Tim - Jan 21, 2006
参考サイト(訳者による追加)
- RMagickオンラインドキュメント:http://www.simplesystems.org/RMagick/doc/index.html
- thumbnailメソッド:http://www.simplesystems.org/RMagick/doc/image3.html#thumbnail
- sampleメソッド:http://www.simplesystems.org/RMagick/doc/image3.html#sample
- scaleメソッド:http://www.simplesystems.org/RMagick/doc/image3.html#scale
- reseizeメソッド:http://www.simplesystems.org/RMagick/doc/image3.html#resize
- Image::Infoクラスの説明:http://www.simplesystems.org/RMagick/doc/info.html
( - )