Java で gif アニメーションを作りたいと思い、色々と調べる過程で
最小サイズの gif 画像や gif アニメーションを作ってみたので、そのメモ。
以前はJavaのクラスでgifを書き出していましたが、
今回は gif の仕様を調べて、バイナリ出力させています。
LZW 圧縮アルゴリズムのコードを書くのはもう少し時間がかかりそうですが、
ヘッダや大まかな構造は次のページを参考になんとなく理解できました。
・Cover Sheet for the GIF89a Specification
http://www.w3.org/Graphics/GIF/spec-gif89a.txt
・とほほのWWW入門 – GIFフォーマットの詳細
http://www.tohoho-web.com/wwwgif.htm
・プログラムdeタマゴ – GIFフォーマット講座
http://d.hatena.ne.jp/nodamushi/20090531/1243775161
また、最小 gif ファイルについて考察されている下記ページも参考にしました。
・LAMPのテクメモ – 最小サイズのgif (gifのサイズ:43 バイト)
http://ichitech.seesaa.net/article/217482401.html
・yosiopp – 最小のpng画像(gifのサイズ:35 バイト)
http://yosiopp.net/archives/225
そしてせっせとバイナリ打って書き出した gif 画像の 16進コードは以下のとおり。
47 49 46 38 39 61 01 00 01 00 80 00 00 00 00 00 ff ff ff 2c 00 00 00 00 01 00 01 00 00 02 01 04 00 3b
34 バイトになりました。
この gif の大雑把な内容は、次のとおりです。
・画像サイズは1×1ピクセル
・Color Resolution は2^1個
・Global Color Table は2^1個(黒と白)
・Graphic Control Extension は省略(透明色の設定などができない)
・Local Table は無し
・LZW Minimum Code Size は 3 bit
・Image Block Size は 1 byte(0b00000100)
yosiopp様のところで書かれたコードとの違いは、
Image Block の Block Size が 2 が 1 かという箇所くらいで、あとは大体同じのようです。
クリアコード(100)の後に 1 ピクセル分の情報は 3 bit のみなので、
使用する領域は 6 bit、Block Size は 1 byte で十分のようでした。
Color Resolution や Global Color Table を 2^0個(1色)にできれば
更に 3 バイト減らせますが、それは無理でした。
実際に生成した gif 画像はこちら。
↓ここにも載せておきます(黒い点がそれ)。
背景を白色にしたい場合は、32 バイト目の Image Data の下から 4 bit 目を 1 にします。
そのコードは次のようになります。
47 49 46 38 39 61 01 00 01 00 80 00 00 00 00 00 ff ff ff 2c 00 00 00 00 01 00 01 00 00 02 01 0c 00 3b
また、同様にして最小のアニメーション gif を作ってみました。
そのコードは次のとおりです。
47 49 46 38 39 61 01 00 01 00 80 00 00 00 00 00 ff ff ff 21 ff 0b 4e 45 54 53 43 41 50 45 32 2e 30 03 01 00 00 00 2c 00 00 00 00 01 00 01 00 00 02 01 04 00 2c 00 00 00 00 01 00 01 00 00 02 01 0c 00 3b
67 バイトになりました。
Image Block が白と黒の二つになり、Application Extension が追加されたくらいです。
Graphic Control Extension は先ほどと同様に省略できましたが、
その代わりに gif の透過色と、アニメーションの FPS が指定できません。
Application Extension も省略した形にできないかなと色々試しましたが、
流石にそれは無理なようでした。
実際に生成したアニメーションgifはこちら。
↓ここにも載せておきます(黒い点が点滅します)。
次は gif の圧縮形式である LZW アルゴリズムのコードをちゃんと書いて、
Java のコンポーネントに描画されたアニメーションを gif で書き出すプログラムを作ります。
webpで30バイトいけました。
data:image/webp;base64,UklGRhYAAABXRUJQVlA4TAkAAAAvAAAAAIiI/gcA
82, 73, 70, 70, 22, 0, 0, 0, 87, 69, 66, 80, 86, 80, 56, 76, 9, 0, 0, 0, 47, 0, 0, 0, 0, 136, 136, 254, 7, 0
webp v2で22バイト行きました
244, 255, 111, 0, 0, 0, 0, 0, 0, 208, 5, 37, 16, 112, 105, 0, 237, 3, 0, 1, 8, 32
data:application/octet-stream;base64,9P9vAAAAAAAA0AUlEHBgAOMDAAAIIA==