LoginSignup
28

More than 5 years have passed since last update.

PNGの非可逆圧縮ーLossy PNG

Last updated at Posted at 2014-12-23

背景

Webページの高速化するためにはイメージサイズをできるだけ小さくすることが必要です。たとえば、最近のWebページのコンテンツタイプごとのサイズは以下のようのなっており、イメージが全体の半分程度を占めています。

chart.png

さらにイメージの中でのフォーマットは、以下の図のようにJPEGで約半分、PNGとGIFがぞれぞれ1/4ずつとなっています。

chart-2.png

JPEGは基本的に画質のトレードオフでコンテンツ作成者がサイズを決めていると思いますが、GIFやPNGは可逆圧縮のためサイズを小さくすることが難しいです。特に透明画像を使いたい場合はPNGしか選択肢はありませんが、パフォーマンスを考えるとPNGでもサイズをなるべく小さくしたいです。この秋に開催されたO'Reilly Velocity Euro Conferenceでもいつくかのセッションで挙げられていましたが、Lossy PNGを使うことで画像のサイズを小さくできます。

Lossy PNGの原理

PNGの圧縮にはRGBからindex colorに減色する方法がありますが、ここではRGBのままでの非可逆圧縮について説明します。なお、index colorの非可逆圧縮は以下の説明と違うアルゴリズムが必要です。

PNGの圧縮の原理

通常のPNGのエンコーダは、大きく分けて次の3段階の処理で行われます。

  1. スキャンライン化などの前処理
  2. フィルタ処理
  3. 圧縮処理

圧縮処理はDeflate方式で圧縮を行います。これは、よく使われるZIPとほとんど同じです。画像データをそのまま圧縮処理してもあまり圧縮されないため、フィルタ処理でより効率的に圧縮できるよう画像データを変換します。
フィルタ処理を簡単な例で説明します。
例としてR成分だけの赤い画像を考えます。R成分だけを抜き出すと、

190, 191, 192, 193, 194, 193, 192, 191, 190, 189

これを左隣との差分に置き換えると

190, 1, 1, 1, 1, -1, -1, -1, -1, -1

となります。左端は0との差分なのでそのままの値になります。このように変換することでより高い圧縮率を得られます。

非可逆圧縮

差分を計算するところで、少々「うそ」をついて

190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

とすればどうでしょう? デコードした画像は

190, 190, 190, 190, 190, 190, 190, 190, 190, 190

となり、元の微妙な赤の陰影が単色の画像に劣化しますが、より圧縮することができます。
これがPNGの非可逆圧縮の原理です。
こうして出来上がったPNGファイルは通常のPNGファイルと全く同じです。言い換えれば、PNGファイルだけを見て非可逆圧縮されたものか、もともと単色の画像だったかは判別できません。
したがって、非可逆圧縮されたPNGファイルも通常のPNGデコーダでデコードできます。

これがLossy PNGの最大の利点です。WebPなど圧縮率を改善した新しいフォーマットが提案されていますが、使えるWebブラウザは限られています。しかし、Lossy PNGの場合、フォーマットそのものは通常のPNGであるため、ほとんどすべてのWebブラウザで表示できます。

使用したツール

今回はソースコードが確認できる
lossypng
を使用しました。実際の圧縮アルゴリズムは上記より複雑です。
また、圧縮した画像の評価には
dssim
を使用しました。これは画像の評価で標準的に使われているstructual similairityを計算するツールで数字の小さいほど画像間の差がないことを表します。

評価

写真

まず、写真を圧縮してみました。
元画像です。
lena.png
475KB
lossypngは-sオプションで圧縮率を指定できます。-s=0でlosslessで、数字が大きくなるほど圧縮率が大きくなります。以下は何種類かの圧縮率で圧縮した画像です。
lena-lossy-20.png
-s=20 84KB (18%) DSSIM 0.033773
ファイルサイズは元画像の18%まで小さくなりましたが、パッと見た目はほとんど劣化が目立ちません。

lena-lossy-30.png
-s=30 61KB (13%) DSSIM 0.055768
サイズは13%ですが、肌などで劣化がわかるようになりました。

lena-lossy-50.png
-s=50 40KB (8%) DSSIM 0.101474
ここまで小さくすると劣化がはっきりと目立ちます。

lena-lossy-80.png
-s=80 28KB (6%) DSSIM 0.169919
参考までにかなり圧縮率をあげた例です。

まとめ

lossy PNGでサイズを大幅に小さくすることができます。また、表示するために特別なデコーダは必要ないので、PC、モバイルなどのほとんどのWebブラウザで表示可能です。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28