はじめに

ウェブサイトの顔を決めるアイコン要素であるfavicon(ファビコン)ですが、最適化されていないために割とファイルサイズが大きいパターンをちらほら見かけます。

今となってはsvgに対応していたり、png画像をそのまま使えるおかげでサイズの縮小化を行いやすいですが、faviconの定番拡張子であるicoファイルは複数の画像を取り入れたマルチアイコンも可能なので少し厄介です。

とはいえ、gzip(GNU zip)圧縮することで大きくサイズを削減できるので、実際にはほとんど気にする必要はありません。

しかし、PythonのPillowを使うことでicoファイルをgz圧縮無しでもファイルサイズを大きく減らせるという情報を見かけたので、一度やってみることにしました。

使用する画像

今回は当サイトのfavicon用アイコン(16.pngおよび32.png)をテストとして使用し、画像は既にzopflipngを使って最適化されています。

16.pngのファイルサイズは134 bytes32.pngのファイルサイズは166 bytesです。

ファイルのwidthとheightは名前と同じです。

これら画像を使って画像編集ツールのGIMPでicoファイルを作成、そしてもう1つはPythonの画像処理ライブラリであるPillowを使って作成したファイルを使って比較を行います。

テストではGIMP(v2.10.30)、Python(v3.10.0)を使い、それぞれWindows版を使用しています。

実際にテストする場合はそれぞれ使いたい環境をセットアップしてください。

比較

では実際の比較を行うためにファイルを作成します。

GIMP

まずはGIMPでICOファイルを作成します。

通常のICOファイルの作成と同じく、対象ファイルをGIMP内にドラッグアンドドロップし、名前をつけてエクスポートを選択し、拡張子はicoを指定します。

今回の例では対象ファイルの色は白黒しか使っていないため、ファイルの保存には4bpp 1bit アルファ 16色パレットを使います。

オプションの圧縮は描画が乱れてしまうので使用していません。

生成後、GIMPで作成したファイルでは1,078 bytesとなりました。

ただ、元ファイルと比較すると大幅にファイルサイズが増えてしまう結果になっています。

Python(Pillow)

次にPythonのPillowを用いてICOファイルを作成します。

まずはPythonの実行ファイル(Python.exe)があるディレクトリに対象ファイルを移動させます。

その後、Python.exeを実行してPythonを起動し、以下のコマンドを実行します。

from PIL import Image
i16 = Image.open('16.png')
i32 = Image.open('32.png')
i32.save('favicon.ico', sizes=[(16, 16), (32, 32)], append_images=[i16])

生成後、PythonのPillowで作成したファイルでは394 bytesとなりました。

GIMPで作成したファイルと比べると2倍以上の差があります。

gzip圧縮する

これらのファイルをgzip圧縮した際のファイルサイズの変化も調べてみました。

なお、gzip圧縮にはzopfliのアルゴリズムを用ています。

GIMPで作成したファイルでは1,078 bytesから222 bytesへと縮小することができました。

そしてPythonのPillowで作成したファイルでは394 bytesから368 bytesに縮小されています。

というように、gzip圧縮した場合にはGIMPで作成したファイルの方が縮小規模が大きいという結果になっています。

おわりに

ファイル生成時点で明白ですが、それぞれのファイルを処理する方法が異なることから、結果的にPillowで生成したファイルではgzipで圧縮できる幅が少なくなっています。

しかし、ファイル単体ではGIMPでの生成と比べて大幅にファイルサイズを縮小することができているため、かなり限定的ではありますが、gzipを使用しない環境では大きなメリットになるかもしれません。

参考資料