LAMP通販サイトオープン
LAMP通販サイトオープン
2020.04.06
#3
LIG技術研究会

PNGとWebPをバイナリ表示(16進数)で比較してみた|WebP編

はっちゃん

こんにちははっちゃんです。

LIG技術研究会 WebP編3回目!

LIG技術研究会って?
日頃感じているWeb技術に関する疑問や不明な点を、研究員(LIG社員)がそれぞれのアプローチによって紐解いていく会。まだまだ謎が多い。

みんなWebPについてわかりやすく書いてくれているので、自分はちょっと内面をのぞいてみました。そうしたら思いのほか広い世界が広がっていて、画像の奥深さを垣間見ることになりました……。

今回は、PNGとWebPをバイナリ表示(16進数)で比較し、WebPの方が軽くなるのを実際のデータを見て理解していこうと思います。

WebPのおさらい

WebP(ウェッピー)とは、Googleが作った画像フォーマットのことで、一般的にJPGやPNGよりもファイルサイズが軽いのが特徴です。

詳しくは、ぜんちゃんの記事をご参照ください。

今回やること

  1. 1px × 1pxのカラーコード(RGB)#000000のPNG画像を用意。
  2. データ量が多いとターミナルで見辛いため、tinypngでPNG画像を圧縮。
  3. PNG画像を複製し、WebPに変換(変換方法はぜんちゃんの記事をご参考にしてください)。
  4. コマンドで16進数のバイナリ表示し、構造を比較。実際のデータを見て、WebPの方が軽くなるのを理解する。
  5. 同じ要領で、複雑な画像でも比較する。

使用するコマンド

今回は、xxdコマンドを使用して画像ファイルを16進数でターミナルに出力します。
xxd -a [ファイル名]

データの見方

この一行だけ見ると、0列目のデータは8950 4e47 0d0a 1a0a 0000 000d 4948 4452であり、文字列に変換すると.PNG……..IHDRとなっているのがわかります。

専用のエディタアプリで見てみるのも良いですね。

MACのバイナリエディタ「0xED」
http://www.suavetech.com/0xed/

また、バイナリの数がそのままファイルサイズになっているので、少ない方がファイルが軽いということがわかります。

比較してみる

ではこれから拡張子ごとのファイルの構成を見ながら、実際に比較していきましょう。

PNG(82バイト)

ターミナルでファイルが置いてあるディレクトリまでいき、xxd -a png.pngで表示してみます。

00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR
00000010: 0000 0001 0000 0001 0103 0000 0025 db56  .............%.V
00000020: ca00 0000 0350 4c54 4500 0000 a77a 3dda  .....PLTE....z=.
00000030: 0000 000a 4944 4154 08d7 6360 0000 0002  ....IDAT..c`....
00000040: 0001 e221 bc33 0000 0000 4945 4e44 ae42  ...!.3....IEND.B
00000050: 6082                                     `.

構造はざっくり以下のようになっています。

PNG ファイルシグネチャ(8バイト) PNGであることを示す。
16進数でつねに89 50 4E 47 0D 0A 1A 0Aが入る。
IHDR チャンク(25バイト) イメージヘッダ
IDAT チャンク(可変長) イメージデータ
IEND チャンク(12バイト) イメージ終端

(参考ソース:PNGイメージのデータ構造を知ってみる(1)

WebP(44バイト)

同様の手順でxxd -a webp.webpで表示してみます。

00000000: 5249 4646 2400 0000 5745 4250 5650 3820  RIFF$...WEBPVP8
00000010: 1800 0000 3001 009d 012a 0100 0100 02c0  ....0....*......
00000020: 4c25 a400 0370 00fe f81f 8000            L%...p......

PNGより圧倒的に軽いですね。縦横1pxの画像ですらこんなに差が出るので、もっと複雑な画像ならさらに顕著に差が現れると思います。

構造はざっくり以下のようになっています。

WebP file header(12バイト)

‘RIFF’、File Size、’WEBP’のまとまり。

RIFF(4バイト) Resource Interchange File Formatの略。
ファイル形式。
File Size(4バイト) 32ビット, Little endian
endianはバイトの並べ方方式のことで、Little endianは逆に並べられる。
‘WEBP’(4バイト) WebPのデータであることを示す。

(参考ソース:WebP の構造を追ってみる 🏗 | Basicinc Enjoy Hacking!

PNGの固定長の幅が45バイト、WebPの固定長の幅が12バイトなので、固定長部分だけで33バイトも少ないことがわかりました。

また、可変長部分もPNGは37バイト、WebPは32バイトと、全体的にPNGより軽いです。

複雑な画像で比較してみる

ファイルサイズが小さいとあまり差が出ないので、複雑な画像で比較してみます。

こちらも同様に、tinypngで圧縮済みです。

PNG(70KB)

00000000: 8950 4E47 0D0A 1A0A 0000 000D 4948 4452  .PNG........IHDR
00000010: 0000 033E 0000 017C 0803 0000 0039 1A9E  ...>...|.....9..	
.
.
.
.
.
.
000111c0: 064f f0f0 9900 0000 0049 454e 44ae 4260  .O.......IEND.B`
000111d0: 82                                       .

WebP(14KB)

00000000: 5249 4646 0036 0000 5745 4250 5650 3820  RIFF.6..WEBPVP8
00000010: f435 0000 f029 019d 012a 3e03 7c01 3e6d  .5...)...*>.|.>m
.
.
.
.
.
.
000035f0: f57f dfb3 6dcf 352d 5950 fff9 6f73 3ec2  ....m.5-YP..os>.
00003600: 87dc 0486 0000 0000                      ........

少しでも色数が多いファイルをバイナリで表示すると、とんでもない行数になってしまい、ここに載せきれませんでした……。

ですが、タイトルのバイト数をみてもわかるとおり、半分以下まで小さくなっています。行数も、WebPの方が一桁少ないです。PNG、WebPの可変長部分の差が大きく出た証拠です。

まとめ

拡張子ごとにデータの構成が違うので、単純な比較は難しいのですが、WebPはデータ量が少ないので、構成がよりシンプルに設計されていることがわかりました。

興味がある方は、構造の細かい概念まで調べて、データの宇宙旅行を楽しんでみてはいかがでしょうか?(理解が深い方、ぜひご教授いただきたいです!)

ほかのLIG技術研究会のWebPの記事もあわせて読んでいただき、制作に生かしていただけたらなによりです。

👉連載:LIG技術研究会

読んでいただきありがとうございました。