webp vs avif vs jpeg2000

# これは何？

つい先日 avif という形式が使いやすそうだという記事を読み。
webp とどっちがいいの？　と思い。

そういえば圧縮対決の記事見てないなと思い。
対決させてみた。

せっかくなので jpeg2000 も参戦。

使い方とか全然書いてないけど、コードは
https://github.com/nabetani/webpavif
においた。

# サンプル画像
サンプル画像は、以下の 6 枚を用いた。（全部自前）

|名前|サイズ|画像|
|:--|:--|:--|
|cloud|800x800|雲の写真を加工
|dog|40x40|絵文字の犬|
|ham|800x800|うちのハムスター|
|jfish|800x800|水族館で撮ったクラゲ|
|turtle|40x40|フリーボードの亀（2色）
|voro|800x800|面塗りたくさん

# 評価方法

画像の劣化具合の評価は

1. 元画像（PNG）を imagemagick で webp・avif・jpeg のいずれかに変換
1. 変換前と変換後の画素値の差の2乗の平均を取る。
1. 得られた値の平方根を評価値とする

という方法にした。

で、劣化具合と出来上がったファイルのバイト数の関係を両対数グラフにプロットした。

ファイルサイズは 変換元の PNG に対する比率で記載した。

変換は、単に

```
$ magick 元画像 -quality 品質 変換先
```

で行った。「こうすればもっと高圧縮になるよ」みたいなことがあるかもしれないけど、その調査はしていない。

imagemagick 以外の方がいいよ、とかいうこともあるかもしれないけど、その調査もしていない。

「品質」の部分に 1〜99 を入れた。
たぶん 100 だと可逆圧縮になって対数グラフに書けなくなるので 99 でやめている。

## わかっている問題点

シンプルに比較できるということでこの方法を選んだが、本当は人間が見て差を感じないような工夫という点で webp・avif・jpeg2000 は jpeg より優れているのであって、この方法で正当に性能が評価されるような気がしない。

とはいえ、現実的に選べる方法でこれより良いものが思いつかなかったので仕方ない。

# 調査結果
## cloud

画像はこんな感じ。

![cloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/3f49d8cd-854c-5c86-61ce-c1d17a0f7cc8.png)

情報多めの実写という気持ち。こんな風景は存在しないけど。

結果は下図。

![cloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/c4b4a116-9ad9-7fdd-8caf-9e924df6b7ff.png)

Quality 1, 50, 75, 90, 99 に、ドットを 大小大小大 と打っている。

意外と jpeg が健闘する。
jpeg2000 はどんどん下に行っているが、PNG とほぼ同サイズなのであまりメリットはない。

## dog

画像はこんな感じ。

![dog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/795f543d-f997-072e-ba70-d3ad355cc03c.png)

カラーアイコンという文脈を想定した。

結果は下図。

![dog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/eca1352b-28fb-e4fb-73bc-85f402d79085.png)

avif・webp はサチる感じ。
jpeg2000 の圧勝。

webp vs avif という観点だと、webp の完全勝利。

## ham

![ham.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/fcae0e3e-e76a-4aec-6cee-5969d4bf4c8d.png)

毛並みという高周波数成分との戦い。

結果は下図。

![ham.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/cf4e31ff-b928-3cca-3bd9-6f9ef46c2b59.png)

webp vs avif という観点だと、avif の完全勝利。

それにしても jpeg2000 の追い込みがすごい。

## jfish

![jfish.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/ed1f938f-6d96-3681-11fd-0651ed920b93.png)

情報少なめの実写。

調査結果は下図。

![jfish.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/9ee5fd8e-fce4-befd-c433-d46402893fdb.png)

avif・webp がサチっている間に jpeg が抜き去っている。
jpeg2000 はサチらずに jpeg とは違うのだよ、という性能を見せている。

webp vs avif という観点だと、互角かな。

## turtle

![turtle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/0281b938-6d6d-9c46-7435-8ed121513282.png)

モノクロアイコンという気持ち。
二値ではなく、境界にはグレーがある。

調査結果は下図。

![turtle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/5824aaa2-9d1c-7964-02d4-61499258534e.png)

また違う傾向になっている。

avif は、低クオリティ側だと jpeg にも負ける低成績で、高クオリティ側に振り切るとだいぶいい絵がでるらしい。

webp はだいぶ良い。
webp vs avif は webp の勝利かな。

しかし jpeg2000 が圧倒的に強い。

## voro

![voro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/00ef7b86-4488-de57-1efe-4e3ef1934134.png)

細かい面塗りたくさんという絵。
各面は単色だけど、境界には適宜中間色が入っている。

結果は下図。
![voro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/5a20c041-d75b-103a-4a11-37390cb3bca2.png)

低品質側では avif が健闘しているが、高クオリティ側では振るわず、jpeg にも劣る。

一方 jpeg2000 はサチらずに誤差を減らしてくる。すごい。

# Quality99 と 100

それぞれの画像・フォーマットで、Quality 99 と 100 でどうなるかを試した結果が下図。

![hiq.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/5581f424-1994-35d0-7404-e0fc296e1603.png)


点が打ってあるのが 100。打ってないほうが 99。

こうしてみると

* 全例で PNG より小さく、全例で可逆になっているのは webp だけ
* avif は quality 100 でも可逆になるとは限らない

ということがわかる。可逆にしたければ webp がわりと優秀。

# まとめ

予想通り、得手不得手があった。

avif・webp よりひと世代古いかなと思っていた jpeg2000 だけど、この評価方法だと結構優秀。
あまり使われていないのは権利的な問題だったのか、あるいは計算量が多いとかそういう理由なのかなぁ。

一番古い jpeg も思ったほど悪くない印象。もっと差があるんだと思っていた。

この結果を見る限り webp から avif に乗り換えてもメリットはあまりなさそう。
私としては、当面ラスタ画像は webp で行こうと思う。