画像ファイルのサイズを低減することで、レンダリング完了までの時間を短縮したりサーバの転送容量を減らすことができます。ここでは、画質を(なるべく)保ったまま、ファイルサイズを劇的に小さくできるJPEGエンコーダとして有名な、MozjpegとGuetzliについてその最新バージョン(2019年2月現在)を用いて性能を検証します。
検証に用いたソフトウェア
Mozjpeg
Mozilaが開発している高性能なJPEGエンコーダ。今回は最新版のmozjpeg Version 3.3.1 (Release date : 24 Mar 2018)を使用。 開発サイトは以下。2019年2月現在、活発に開発されています。
本家のサイトでは(なぜか)ソースコードしか配布されていないですが、 探すと最新版のWindows用バイナリを配布しているナイスな人がいるので、今回はこれを用いました。
ダウンロードすると複数のバイナリーファイルが入ってます。それぞれ、以下の用途に使えます。
- cjpeg : (lossy) JPEGエンコーダ
- djpeg : JPEGデコーダ
- jpegtran : (lossless) JPEGエンコーダ
- rdjpgcom : JPEGファイルのコメントを抽出して表示
- wrjpgcom : JPEGファイルにコメントを記入
今回は、cjpegとjpegtranを使いました。
Guetzli
Google製のJPEGエンコーダ。人間の視覚的な特性を考慮して画質の違いを数値化できるbutteraugliを使って、このスコアが良くなるようにひたすらパラメータを変えてJPEGエンコードを行い、ファイルサイズが小さくて画質劣化の少ない画像を生成するらしいです。 本家のサイトは以下。
ここでwindows用のバイナリーも入手できます。 今回は、Guetzli v1.0.1 (Release date: 22 Mar 2017)を用いました。
評価項目
Qualityパラメータを変えて、以下の項目について比較検証しました。
- ファイルサイズ
- 画質 (butteraugliスコア)
- 変換時間
画質の評価はGoogle製butteraugliを使い数値化しました。値が0に近いほどオリジナルの画像に近い画質です。 Guetzliはbutteraugliのスコアを指標にして最適化を行うので、ちょっとフェアでないですが、これ以外のツールが見つからなかったので今回はbutteraugliを使用しました。
検証環境
今回はWindows10+AMD環境でテストしましたが、他の環境でも傾向は一緒(のはず)
- OS : Windows10 1803 (ビルド 17134.590)
- CPU : AMD Ryzen 5 2600 (6C12T, base clock:3.4GHz)
- Mem: 16GB (DDR4)
- DISK; SSD 480GB (SATA6G接続; SanDisk SDSSDXPS480G)
テスト環境の詳細は、以下のエントリを参照してください。
検証に使った画像
筆者の撮影した画像を3枚用いました。JPEG画像でありがちな食品の画像、自然の画像、街の画像をチョイスしました。 (すべてAndroidスマートフォン(SONY XPERIA)の撮影。アプリケーションはメーカ製のプリインストールアプリを使用) こんな感じの画像です(参考画像。オリジナルの10%まで縮小した後に結合し1枚の画像にしています)。
ファイルサイズと解像度は以下のとおりです。
Name | File size (MB) | Resolution (px) |
---|---|---|
Image 1 | 6.27 | 5056 x 3792 |
Image 2 | 7.30 | 3000 x 4000 |
Image 3 | 4.57 | 3000 x 4000 |
検証結果
Mozjpeg (jpegtran : lossless encoding)
まず、ロスレスエンコーダである、jpegtranの結果から。
Name | Original size (MB) | New size | Reduced % | Execution time (sec) | Butteraugli score |
---|---|---|---|---|---|
image 1 | 6.58 | 5.96 | 90.57 | 5.861 | 0.0 |
image 2 | 7.66 | 6.48 | 84.59 | 4.684 | 0.0 |
image 3 | 4.79 | 4.13 | 86.22 | 2.646 | 0.0 |
平均すると、10~15%の圧縮効果があり、変換時間は数秒でした。ロスレス圧縮なので当たり前ですが、Butteraugli scoreは0.0(同一画質)です。
Mozjpeg (cjpeg)
つづいて、(本命の)cjpegの結果。 実行時のQualityパラメータの値と、ファイルサイズ、実行時間、Butteraugli scoreのグラフです。 (ファイルサイズはオリジナルのファイルを100%として正規化しています。)
ここからわかるのは、
- Q=100はオリジナルよりファイルサイズが大きくなる上、画質が落ちるので使う意味なし。
- ファイルサイズが急激に小さくなるのはQ=80ぐらいまでで、それ以降の変化は小さい。
- 実行時間はほぼすべての条件において10秒以下で、Qが小さいほど早くなる。
- Q<50で、Butteraugli scoreが急激に大きくなる(画質が大きく低下する)
正直、Q=60の画像とオリジナル画像を見比べてみたのですがほとんど違いがわかりませんでした。 ファイルサイズとスコアを総合すると、Q=75~80ぐらいがベスト?(デフォルト値はQ=75)
Guetzli
Guetzliについても同様に測定した結果です。GuetzliはQ>=84という制限があるので100~85の間で確認しています。
- ファイルサイズは最大1/3ぐらいまで小さくなる。
- 実行時間は、今回のサンプルだと800~1800秒。
- Qに比例してButteraugli scoreが大きくなる。
コンセプト検証のソフトウェアなので実行時間の話をしても仕方ないですが、Mozjpegとの比較で実行時間が数百倍ぐらいに伸びるのでベンチマークに時間がかかりました…
MozjpegとGuetzliの比較
MozjpegとGuetzliのButteraugli scoreとファイルサイズを比較してみました。グラフの左下にいくほど画質が良くてファイルサイズが小さいことを意味しています。
あれ、あまり変わらない? 拡大してみると、
Image 2では明らかに同じ画質でGuetzliのほうがファイルサイズが小さくなってますね。 他の画像は、Guetzliのほうがやや良いか、Mozjpegとあまり変わらない結果になりました。 ただ悪くなるわけでもないので、実行速度さえ実用的になればGuetzliは良いアルゴリズムとも言えます。
まとめ
- とりあえず、jpegtranを使うと画質を一切落とさず(オリジナルと同じ画質で)10~15%のファイルサイズ削減効果が期待できる。
- ウェブページに貼り付けるぐらいの用途ならcjpegでQ=75~80とかで再圧縮することで、ほとんど画質に影響を与えることなくファイルサイズを半分以下にできる。
- Guetzliは処理に時間がかかりすぎるので現状では実用的ではないが、同じ画質の画像をより小さいファイルサイズで実現できそう。(今後に期待)
webページ用途だと、mozjpegでJPEGのファイルサイズを半分以下にすることで、サーバの転送容量の削減やページロード速度の向上が期待できそう。
関連記事
PNGファイルの最適化:
最適化をドラックアンドドロップで行えるバッチファイル