selflearn @ ウィキ

Making Thumbnails with RMagick

最終更新:

selflearn

- view
メンバー限定 登録/ログイン

Making Thumbnails with RMagick


開始日 2007年02月01日
最終更新日 2009年06月03日

はじめに

Polaroid Effectが好評なので、調子に乗って別のページも翻訳し始めました。

原著


「Making Thumbnails with RMagick」
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と一緒に使っているならば、これは良い選択肢だと思わないか?

以下の内容を読んで、私がなぜこのような結論に至ったかを見てほしい。

RMagickでサムネイルを作るには

RMagickは、ImageMagickまたはGraphicsMagickライブラリのRubyバインディングだ。ImageMagick/GraphicsMagick双方のライブラリは画像リサイズ用の同じAPI一式を提供していて、RMagickではMagick::Imageクラスのresize、sample、scale、そしてthumbnailメソッドでこれらAPIをラップしている。
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の結果に注目してくれないか。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よりも速い。まぁ、人によってはこれでもいいかもしれない。

そうだ、thumbnail以外の方法を使った場合、出来上がったサムネイルからプロファイルやコメント情報をstripすることを忘れないでくれ。

巨大なJPEGファイルをサムネイル化するときのTips

サムネイル化したい画像が巨大ファイルサイズのJPEGデータだった場合、全データの読み込み&画像処理よりもっと良い方法がある。
それはImage::Infoの属性self.sizeを指定してファイルを読むことだ。求めているサムネイルサイズのちょうど2倍のサイズを指定してから読み込むと、ImageMagickのJPEGライブラリはファイルのデータ全部を読み込まず、必要な量だけを読み込んでくれるというわけだ。その後、適度に小さくなって読み込まれた画像を使ってサムネイル化する。
大きなファイルの読み込みはメモリを圧迫して無駄も多いので、ぜひ活用してほしい。

詳細な説明は、AnthonyのExcelletなサイトにある「Reading JPEG Image」の項に載っているから、こちらも参照してくれ。
(この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を使用している。

Tim - Jan 21, 2006


参考サイト(訳者による追加)



-

タグ:

Ruby RMagick
記事メニュー
目安箱バナー
注釈

*1 訳注:原著は「CPU時間がどれだけ割り当てられるか」という文が書かれています。

*2 訳注:現在(2007/2/2)のImageMagickの最新版は6.3.2です。

*3 訳注:原著は色んなメソッドの説明がごちゃ混ぜになっていたので表にまとめました

*4 訳注:最近はディスプレイも高解像度化してますし、ブログに富豪的サイズの画像を載せる人も多くなりましたから、400x300でもサムネイルに含まれてしまうでしょうね。