ファイルサイズ小のために(その1)

= Global Color Table =

ファイルサイズを小さくする為には、なるべく Global Color Table を利用すべし。

Global Color Table とはGIFファイル内にたった一つのみ存在し得る共通のパレットの事である。
また、Local Color Table というものも存在し、これは各フレームが個々に持つ事ができるパレットの事である。
これ GIF における基本なり。

例えば 256 の色を持つフレームならば、そのパレットのサイズは
3 byte x 256 = 768 byte
となる。

各ケースの例を表で示す。
色数 サイズ(byte)
2 6
4 12
8 24
16 48
32 96
64 192
128 384
256 768
色数が少ない場合は大した事は無いが、256 色にもなるとパレット1つで 768 byte のサイズになる。
フレームが 10 個あった場合、その全てで Local Color Table を使用していたりすると、
768 byte x 10 = 7680 byte
約 7k byte のサイズにもなる。
逆に全てを Global Color Table で済ます事ができれば
768 byte x 1 = 768 byte
となり、全てに Local Color Table を使用した時との差は 6912 byte にもなる。


ここまで読んで、「Global…やらLocal…自体の意味が解らんのだよ!」
という者のために図も示しておく。
Picture 1
感覚は掴めるだろう。


− なるべく Global Color Table を使用するために −

元画像を作成する段階から、パレットを1つしか使用しない事。
…だが、何時もそうできるハズがない。

よって「natm」ではパレットを統一する機能を提供している。
メニューの [編集] -> [パレットを統一する] がそれにあたる。

Picture 2
メニューを実行すると、このダイアログが表示される

各部の説明。
条件1 登録されている全てのフレームを対象とするか、現在選択しているフレームを対象にするかを指定。
条件2 対象とする色数を指定。
条件1を満たしたフレームの内で、ここで指定された色数を持つフレームが最終的な対象フレームとなる。
処理後、Global … 統一されたパレットは Global Color Table に設定される。
要は、その統一されたパレットを使うかどうかという事。
透過色用に確保… 現在透過色が設定されていないフレームにも透過色を適用する。
既に透過色が設定されているフレームには自動的に適用される。
透過色用の色を…ON の時のみ有効。
色数 統一するパレットの持つ色数。
当然の事だが、元画像のパレットよりも多い色数を指定するとファイルサイズは大きくなる。
少ない色数を指定すると、ファイルサイズは小さくなるが画像の品質の劣化度が増す。
背景色用の色を… 統一するパレットに背景色のためだけの色を用意するか?という事。
この項目が ON の場合は、イメージに使用するための色は一つ減らされる。(例えば元々 256 色で描画していた画像の場合、1色減らした 255 色で描画する事になる)
色はパレットの最後の位置(透過色も確保した時は最後の1つ前)に確保される。
透過色用の色を… 統一するパレットに透過色のためだけの色を用意するか?という事。
後は 背景色用の色を… を参照。
対象フレームの中に透過色が設定されたフレームが在る場合は、強制的に ON 扱いとなる。

この機能を用いる事で統一されたパレットを作成する事ができる。
が、無理な統一を行う事はお奨めできない。

パレットの統一とは、要は使える色数を(場合によっては)減らして無理やりに1つのパレットに纏め上げる事である。
全く違う色が多く使われているフレーム同士のパレットを統一すると、無理をしたパレットができあがる。
結果、元画像とあまり似ていないイメージになる可能性もある。

逆に、似た色が多く使われているフレーム同士の統一であればほとんど問題は無い。

と色々述べておきながら、最後に適当な事を言うようだが、
アニメーションさせようとしている画像ならば、自然と似た色が使われる事が多くなるだろう。
よって、深く考えずにパレットの統一をしても問題が無いというケースも多い。


ファイルサイズ小のために(その2)

= 無駄な画像情報の省略 =

ファイルサイズを小さくする為には、なるべく重複するデータを削るべし。

GIFアニメ の再生に画面全体の画像情報など、かけら程しかいらん。
必要なのはアニメーションによって変化が起こる部分の画像情報のみ。
つまり、変化の起きない部分の画像情報はとことん捨てる − 的確な取捨選択をする事が大事なのだ。

Picture 3
ファイルサイズ 860 byte

例えばこの GIF の場合、以下の4つのフレームから成り立っている。
Picture 3.1 Picture 3.2 Picture 3.3 Picture 3.4
所謂、全てのフレームが画面全体の画像情報を持っている GIF である。


また、この GIF を見て欲しい。
Picture 4
ファイルサイズ 414 byte

表示されているイメージは先に見せた GIF と全く同じハズだ。
だが、ファイルサイズは半分以下になっている。
これは、変化の起きない部分の画像情報を捨てたためだ。

因みにフレームはこのような構成になっている。
Picture 4.1 Picture 4.2 Picture 4.3 Picture 4.4
ファイルサイズが小さくなった要因は一目瞭然だ。


− 不要な画像情報を捨て、必要な画像情報のみを得るために −

アニメーションを1コマ毎に比較して変化をチェックすべし。
そうして取り出した画像をフレームに登録し、適切な配置位置を指定すべし。
…なんて事はやってられない。

という事で「natm」では必要な画像情報のみを取り出すための機能を提供している。
メニューの [編集] -> [現在の設定で最適化] がそれにあたる。([ファイル] -> [保存] でも可)

Picture 5
メニューを実行すると、このダイアログが表示される

各部の説明。
透過色を利用して… GIF で使われているデータ圧縮法(LZW)には、同じデータ(パターン)が(水平方向に)連続すると圧縮効率が高まるという傾向がある。
この事を踏まえた上で話を進める。
2つのフレーム Picture 6.1 Picture 6.2 から成るGIF Picture 6 が在る。
見れば判るハズだが、この GIF は”顔”の部分が変化しているだけで”背景”は変化していない。
つまりこれは、”背景”の部分は最初のフレームが持っていれば十分という事になる。
実際に Picture 7.1 Picture 7.2 から成るGIF Picture 7 を作ってみた。
 #008080 を透過色に指定している)
見た目は全く同じだ。だがファイルサイズは 4973 byte,2904 byteと明らかな差が出ている。
使用しているパレットの色数(64色)も、画像の縦横のサイズ(64x64)も同じなのにである。

これが透過色を利用して圧縮効率upを狙うという事である。
透過色に置き換える事によって、同じデータが連続するようになり圧縮効率が高まったのである。
稀に、圧縮効率が逆に悪くなってファイルサイズが増えてしまうケースがある。
このケースは、ベタ塗りされている領域が多い画像ほど起こり得る。
ベタ塗り領域が多い画像は必然的に同じデータが連続している可能性も高くなる。
つまり、元から圧縮効率が高い可能性があるためだ。
画面イメージに… 例えば Picture 8.1 Picture 8.2 Picture 8.3 から成るGIFが在る。
だが1フレーム目と2フレーム目は全く同じ画像のため、見た目に変化はない。
このようなフレーム(例では2フレーム目)は削除しようという機能である。
見た目上は意味が無くても 待機時間ユーザー入力 といった項で意味を持っている可能性もある。その辺りの判断は必要。

この機能を用いる事で必要な画像情報のみを取り出す事ができる。

が、それには条件がある。
その条件とは、フレームの「背景の処理方法」

の何れかであるという事である。(0:「指定しない」1:「現在のまま」と同じ扱いという前提)

2:「背景色で塗り潰し」 はフレーム(画像)の縦横サイズ自体が意味を持つため、画像情報を捨てる事はできない。
だが、透過色を利用して圧縮効率upを狙う 事だけならば可能である。


原案: mk.Tiby に多謝。