可逆画像圧縮の本当の仕組み
なぜファイルを小さくしても元の画像とピクセル単位で完全に同一でいられるのか — それを実現する予測・モデリング・エントロピー符号化のテクニックを解説します。
なぜファイルを小さくしても元の画像とピクセル単位で完全に同一でいられるのか — それを実現する予測・モデリング・エントロピー符号化のテクニックを解説します。
「ロスレス(可逆)」というのは一見矛盾しているように聞こえます。何も捨てずにファイルを小さくできるのはなぜでしょうか。その秘密は、画像には<b>冗長性</b>がたっぷり含まれているということです。圧縮とは、同じピクセルをより少ないビットで表現する技術なのです。デコードすれば元の値がすべて、ビット単位で正確に戻ってきます。
JPEGのような非可逆(ロッシー)フォーマットは、目でほとんど気づかないであろう情報を捨てます。ロスレス圧縮は<i>何も</i>捨てません — デコードした画像は入力と完全に同一です。だからこそスクリーンショット、線画、ロゴ、UIアセット、アーカイブ用マスターに最適な選択肢なのです。1ピクセルでもずれれば丸め誤差ではなくバグになってしまうものすべてに当てはまります。
生のピクセルは無駄が多いものです。なぜなら隣接するピクセルは強く相関しているからです — 左隣のピクセルは、たいてい現在のピクセルの良い推測値になります。ロスレスコーデックは各ピクセルを隣接ピクセルから<b>予測</b>し、わずかな誤差(残差)だけを保存します。PNGではこれを<i>フィルター</i>(Sub、Up、Average、Paeth)と呼びます。予測が優れているほど残差はゼロ付近に集まり、ゼロは見事に圧縮できます。
データの大半が小さく反復的な残差になったところで、<b>エントロピー符号化器</b>が頻出する値には短い符号を、まれな値には長い符号を割り当てます。PNGはDEFLATE(LZ77 + ハフマン符号)を使用します。WebPロスレスやJPEG XLのようなモダンなコーデックはコンテキストモデリングと算術符号化やANS符号化を使い、理論上の限界により近づきます。フォーマットは変わっても考え方は同じです — 予測可能な部分に費やすビット数を減らすということです。
だからこそ、同じ画像から作った2つのロスレスPNGでもサイズが大きく異なることがあります。ピクセルは同一でも、エンコーダーがそれを表現するためにどれだけ手間をかけたかが違うのです。<b>oxipng</b>はフィルター戦略を探索して再圧縮し、<b>zopfli</b>ははるかに低速なDEFLATEでさらに数パーセント削ることが多く、WebPとJPEG XLはまったく賢いモデルを持ち込みます。いずれもピクセルには一切手を加えません。
# ロスレス・最大負荷設定 — ピクセルは同一、ファイルはより小さく imageforge logo.png --lossless --effort max imageforge ui-export.png --convert webp --lossless
ロスレスにも限界はあります。実写のシーンには本物の高周波ディテール(センサーノイズや細かいテクスチャ)が含まれており、これはうまく予測できないため、そこでのロスレスの効果は控えめです — そこで非可逆フォーマットの出番となります。一方、フラットで合成的、あるいはテキストが多い画像であれば、ロスレスは画質を一切犠牲にすることなく日常的に30〜70%削減できます。腕の見せどころは、自分の画像がどちらに当てはまるかを見極めることです。
ImageForgeがoxipng、zopfli、モダンなロスレスエンコーダーをあなたの代わりに実行します — すべてローカルで。