WebPとAVIFのどっちに統一するか実測したら可逆と非可逆で結論が逆だった

手元の画像フォルダがPNGとJPEGとWebPとAVIFで混ざってて気持ち悪いので、どれかに統一したくなった。

調べると「AVIFのほうが新しくて小さい」と書いてある記事ばかり出てくる。じゃあAVIFでいいかと思ったんだけど、念のため自分で測ってみたら可逆と非可逆で結論が逆になった。丸ごと書いておく。

測り方

比較の軸はSSIMにした。同じSSIMになる点でバイト数を比べれば、画質を揃えた上での大小が言える。

ここで最初に踏んだ地雷が2つある。ひとつは輝度だけのSSIMでは420と444を比較できないこと。色差を間引いた劣化が輝度に出ないので、420のほうが不当に有利に出る。RGBの3チャンネルで測る必要がある。計測器が正しいかは、同じ画像同士でSSIMが1.0になるか、可逆圧縮したものとの比較で1.0になるかで検証した。

もうひとつが基準にするPNGだ。ブラウザのcanvasから吐いたPNGは、実在のPNGより4割大きい。同じ画像で829,858バイト対566,432バイトになった。これを基準にすると圧縮率が水増しされるので、配布されてるファイルの実サイズを使わないといけない。

合成画像で測って失敗した

最初、イラストの比較用に自分で合成画像を作って測った。結果は「イラストなら非可逆AVIFが全面的に勝つ」で、いい記事が書けそうだと思った。

間違いだった。実物のイラストで測り直したら成立しなかった。原因は色数で、それっぽく作った合成画像は色数が1,229から10,627しかなくて単純すぎた。実物のアニメ調イラストは色数が3,701から293,142まであって、写真並みかそれ以上のものもある。

合成画像でコーデックを評価してはいけない。ここは声を大にして言いたい。以下の数字は全部、実物で測り直したものだ。

可逆はWebPの圧勝

まず可逆から。PNGを100としたときのサイズで比べる。

写真ではWebPが72から74%、AVIFが87から92%。WebPの勝ち。イラスト8枚ではWebPが43から75%で、AVIFは70から106%。AVIFの可逆はPNGに負けることすらある。8枚全部でWebPが勝って、AVIFはWebPの113%から250%というひどい負け方をした。

極端なのが文字の多い画像で、WebP可逆がPNGの6%まで縮むのに対してAVIF可逆は62%。実数だとWebPが9,280バイト、AVIFが88,744バイトで、10倍近い差がついた。VP8Lという可逆用の仕組みがこの種の画像に異常に強い。

結論として、可逆圧縮器としてのAVIFを選ぶ理由は無い。

非可逆はAVIFが強い

ところが非可逆にすると逆転する。

写真では同じSSIMでAVIFがWebPの77から87%。安定して2割ほど小さい。既存のJPEGを移行する場合も、元のJPEGに対するSSIMを0.98に揃えるとAVIFが51から68%、WebPが70から98%で、AVIFが明確に有利だった。

いちばん差が出るのが文字の入った画像だ。WebPの非可逆は品質を上げても頭打ちになる。quality 95まで上げてもSSIMが0.9592で止まる。AVIFはquality 50の時点で0.9945に達する。

原因はコーデックの世代ではなくて色差の間引きだった。WebPの非可逆はYUV420固定で444を持たない。色差を半分に間引く以上、細い色の境界の滲みは品質を上げても取れない。AVIFで444を選べるから壁が無いだけで、AVIFでも420にすると同じくSSIM 0.958で頭打ちになる。AV1がVP8より優れてるという話ではない。

イラストは決着しない

イラストの非可逆だけは結論が出せなかった。

SSIM 0.99に揃えて必要なバイト数を比べると、ある絵ではAVIFがWebPの61%で、別の絵では156%。両方向に2.5倍の幅で振れる。同じquality 85同士で比べてもSSIMの勝敗が5対3で割れた。

だから「イラストならこっち」という言い方はできない。絵ごとに測るしかない。

どっちに寄せるか

整理するとこうなる。

可逆を1枚でも残したいならWebP。可逆で使えないAVIFを選ぶ理由が無い。可逆を捨てて非可逆で揃えるなら、写真中心ならAVIF、絵中心なら差が振れるので決め手にならない。拡張子を1つにしたいだけなら、WebPもAVIFも中に可逆と非可逆の両方を入れられるので、どちらでも混在は解消できる。

自分の場合は可逆を捨てたくなかったので、WebPに寄せることにした。

変換して損する組み合わせ

手持ちのファイルを一括変換するときのために、変換元別の損得も測った。AVIFへ寄せる場合の数字だ。

PNGの写真をquality 70のAVIFにすると8から9%まで縮む。これは劇的に得。ところがJPEGをロスレスAVIFに変換すると548から607%に膨らむ。元が非可逆のものを可逆で包み直すので当然といえば当然なんだけど、一括変換のスクリプトを雑に回すとこれをやる。

いちばんひどいのが可逆WebPの文字画像で、ロスレスAVIFにすると956%、quality 70でも220から569%。可逆WebPの文字画像は絶対に変換しない。10倍近く太る。

非可逆WebPからAVIFへの変換も、写真で84から92%、文字画像だと102から106%とほぼ無意味だった。1割減るか、むしろ増える。すでにWebPにしてあるものを追いかけてAVIFにする価値は無い。

対応状況

ブラウザ対応はAVIFが94.67%⁽¹⁾で、SafariはiOS 16.4の2023年3月から。WebPはそれより数年早いので、対応の広さではWebPが有利だ。ただAVIFも9割を超えてるので、今から使う分にはどちらでも実害は無いと思う。

SSIMを使う理由と限界

指標にSSIMを選んだ理由も書いておく。

単純にファイルサイズだけ比べると、画質が違うものを比べることになって意味が無い。かといって目で見て決めると再現性が無い。同じ画質になる点を数値で揃えてからサイズを比べるのが、いちばん揉めない。

ただしSSIMが人間の見え方と完全に一致するわけではない。数値が同じでも、劣化の出方は形式によって違う。JPEG系はブロック状に崩れ、AV1系はのっぺりと平滑化される方向に崩れる。どちらが気になるかは見る人と絵による。

だから最終的には目で確かめる工程が要る。数値は候補を絞るための道具で、決定するのは自分の目だ。ここを飛ばすと、数字の上では優秀なのに見た目が気に入らない設定に落ち着くことがある。

品質の設定値をどう決めるか

実運用で困るのが、qualityをいくつにするかだ。

同じ数字でも形式によって意味が違う。WebPのquality 85とAVIFのquality 85は別物で、比べても仕方がない。設定値ではなく到達したSSIMで揃えるのが正しい比較で、この記事の数字も全部そうやって出してる。

自分の手元では、写真ならSSIM 0.98あたりを狙うと目で見て違和感が出ない。文字や線画が入るなら0.99以上でないと境界が滲む。この閾値を先に決めて、そこに到達する設定値を形式ごとに探す、という順番でやってる。

面倒に見えるけど、一度決めれば使い回せる。逆に「とりあえず品質80」で全部変換すると、文字の入った画像だけ静かに壊れる。

一括変換で気をつけること

フォルダ丸ごと変換するスクリプトを書くなら、最低限やっておきたいことが3つある。

ひとつ、変換前後のサイズを比べて、太ったファイルは変換をやめて元を残す。この記事で見たとおり、組み合わせによっては10倍になる。無条件に上書きするスクリプトはこれをやる。

ふたつ、元が非可逆かどうかを見て分岐する。JPEGや非可逆WebPを可逆で包み直すのは、ほぼ確実に損だ。拡張子だけでは判断できないので、中を見る必要がある。

みっつ、元ファイルをすぐ消さない。変換結果を目で確かめるまでは両方置いておく。ディスクは安いけど、消した原本は戻ってこない。

透過とアニメーション

今回は測ってないけど、実際の使い分けで効いてくる要素も挙げておく。

透過が要るならPNGかWebPかAVIFで、JPEGは選択肢から外れる。アニメーションが要るならWebPとAVIFのどちらでも扱えるけど、対応してるソフトの数はWebPのほうが多い。

それと、編集ソフトが開けるかどうかが地味に効く。圧縮率が優れていても、手持ちのビューアやエディタが読めない形式に統一すると、毎回変換する羽目になる。この観点でもWebPのほうが枯れてて安全だ。

圧縮率の表だけ見て決めると、こういう運用上の要素を見落とす。数字は判断材料のひとつでしかない。

まとめ

「AVIFが最強」という記事を信じて全部変換してたら、可逆のファイルが軒並み太ってた。特に文字の入った画像は10倍だ。測ってよかった。

教訓としては、圧縮率の話は自分の手持ちの画像で測らないと意味が無い、ということになる。写真とイラストと文字絵で挙動が全然違うし、同じイラストでも絵によって2.5倍振れる。ベンチマーク用の標準画像でいくら測っても、自分のフォルダがどうなるかは分からない。