劣化しがちなJPEG画像を4:4:4サンプリングで綺麗に保存するんじゃ(※当社比)
JPEG画像というのは、いったんYCbCr(YUV)という色空間に変換してから保存しているらしい。
一般的には光の三原色である赤/緑/青の強さで表わすRGB方式が使われるが、YCbCr方式はRGBで表現された値を元に換算式で計算される数値で色を表わす。
Yは輝度で、CrCbは、Cbが青系統、Crが赤系統のそれぞれの色の色相と彩度を表わす。
で、だいたいのソフトウェアでは圧縮方式に4:2:0という圧縮が用いられているらしい。
YUV=4:2:0 YUV=4:2:2でサンプリングしたのち,輝度情報はそのまま残し,色差情報を垂直方向に2ピクセル分平均化(サブサンプリング)して記録するフォーマットです。情報量は,1ピクセル平均12bitになります。
各ピクセルにおいて,輝度情報は256階調のまま記録されていますが,色差情報については,横方向に2ピクセル,縦方向に2ピクセルの計4ピクセルで平均化されたデータが記録されています。
The Anatomy of Chroma Subsampling | Videomaker.com
HD and Beyond: An Introduction to HDMI 2.0 | HiddenWires
H.264やJPEGで赤が劣化しやすいのは、この色差情報の圧縮が原因のようだ。
また、losslessでないWebPの圧縮も、この4:2:0形式で行われているらしい。(元々VP8動画フォーマットがベースらしいので当然か)
WebP は、JPEG の高圧縮版を目指して開発されているように感じる。
そして、WebP は 4:4:4 形式をサポートしておらず、4:2:0 形式になる。
これがどういうことかすぐにわかる画像が以下。青と赤の劣化が激しい。
完全に違う色になっている。
4:2:0 は、色差成分が 1/4 サイズになるので、どうしても青と赤が劣化する。
青と赤成分の画像サイズが 1/4 になっているのに近い。もちろんアルファチャンネルが後から追加されたように、後で 4:4:4 形式が追加される可能性はある
4:4:4 と 4:2:0 で比較してみよう!
というわけで、4:4:4サンプリングで圧縮したJPEGと、4:2:0サンプリングで圧縮したJPEGを比較してみよう。
jpeg変換にはGIMPのエクスポートを、webp変換はwebpをコマンドラインで変換しました。
(※はてなではWebPに対応していないので、可逆変換のPNGで再保存しています)
cwebp.exe -preset drawing -mt -q 95 input_.png -o output_95.webp
元画像 (PNG 236,318 byte)
Quality 95
JPEG 95 4:4:4 (87,344 byte)
JPEG 95 4:2:0 (67,588 byte)
WEBP 95 4:2:0 (43,258 Bytes)
Quality 85
JPEG 85 4:4:4 (50,268 Bytes)
JPEG 85 4:2:0 (38,861 Bytes)
WEBP 85 4:2:0 (24,952 Bytes)
Quality 75
JPEG 75 4:4:4 (38,114 Bytes)
JPEG 75 4:2:0 (29,667 Bytes)
WEBP 75 4:2:0 (17,600 Bytes)
補足
GIMPのほかに、MassiGraでも4:4:4サンプリングでのJPEG保存ができるようです。
IrfanViewもデフォルトでは4:2:0での保存ですが、「カラーサンプリングを無効にする(D)」のチェックを入れると、4:4:4サンプリングでのJPEG保存ができるようです。
どうもついったにJPEG画像を上げると、元の画像が4:4:4でも再圧縮されて強制的に4:2:0にダウンサンプリングされるみたいですね→元画像http://t.co/b22Gi4MN6Y(品質90 4:4:4サンプリングで保存) pic.twitter.com/hcrjEqllKB
— あんこ (@animencode) 2014, 9月 19
@hachunemick 特に関係ないと思います。乱暴に言うとツイッタが圧縮したJPEGは赤色を1/4に間引きして保存して、見るときに引き延ばしているので、その時にJPEG特有のノイズもいっしょに大きくなって目立ちやすくなるんです。 pic.twitter.com/IXQjZzPYbr
— あんこ (@animencode) 2014, 9月 27