本文へスキップ
AZ Tools

GIF 構造インスペクター

GIF をデコーダーと同じ手順で、13 バイトのヘッダーから 0x3B のトレーラーまでブロック単位でたどります。ヘッダーからは、バージョン(GIF87a には拡張ブロックが存在せず、アニメーションできるのは GIF89a です)、フレームを合成する論理画面、背景色インデックス、この 30 年どのブラウザも尊重してこなかった画素アスペクト比バイト、そしてグローバルカラーテーブルの有無・項目数・ビット数が分かります。続いて各フレームを、再生を左右する 2 つの値、すなわち遅延と廃棄方法とともに一覧にします。GIF が遅く見える原因はたいてい遅延です。遅延は 100 分の 1 秒単位で保存され、ブラウザは約 20 ms 未満の値を黙って 100 ms に置き換えるため、1 フレーム 5 ms で作ったファイルは意図の 5 倍遅く再生されます。そこで宣言どおりの合計と、実際に見える長さの両方を示します。廃棄方法は残像やちらつきの原因です。背景に戻すは次のフレームの前にその矩形を消し、直前に戻すはキャンバスを巻き戻し、そのまま残すは変わった画素だけを保存する最適化を可能にします。その最適化の跡もここに現れます。論理画面より小さいフレームには印が付き、位置、ローカルカラーテーブルの有無、インターレースの有無、透過インデックスが並びます。サブブロックの連鎖を推測せずに正確にたどるので、フレームごとのバイト数は正確で、表はそれを並べ替え、ファイルを 20 MB にした張本人が先頭に来ます。残りのバイトはカラーテーブル、LZW 画像データ、ブロックの管理分に分けられ、グラフィック制御・コメント・プレーンテキスト・アプリケーションの各拡張ブロックは、NETSCAPE のループカウンターや未知のものも含めてオフセット・サイズ・本文とともに一覧されます。ただし画素は復号しません。LZW ストリームは大きさを測るだけなので、色の正確さやディザリング、フレーム同士の似かたについては何も言えません。途中で切れたファイルや、ブロック長がファイル末尾を越えるファイルは、中途半端に読まずに名前の付いたエラーで拒否します。その先ではどのオフセットも当て推量になるからです。

使い方

  1. .gif をボックスにドロップするか、クリックして選んでください。バイト列はページ内で読まれ、アップロードはされません。
  2. まず概要を見ます。ヘッダーのバージョン、論理画面、フレーム数、ブラウザでの実際の再生時間、ループの挙動が並びます。
  3. 再生の警告が出たら、フレーム遅延がブラウザの下限を下回っています。20 ms 以上に上げないかぎり、書いた値より必ず遅く再生されます。
  4. サイズの疑問はフレーム表で解きます。バイト列とバーが高くつくフレームを示し、サイズの * はキャンバスの一部だけを描き直すフレームです。
  5. 拡張ブロックの一覧で、NETSCAPE のループブロック、エンコーダーが残したコメント、覚えのないアプリケーションブロックを確認します。

よくある質問

設定した遅延より遅く再生されるのはなぜですか。
ブラウザが極端に短い遅延を受け付けないからです。遅延は各フレームのグラフィック制御拡張に 100 分の 1 秒単位で入るため 0 以外の最小値は 10 ms ですが、Blink と WebKit は 11 ms 未満を、Gecko は 20 ms 未満を 100 ms に置き換えます。その結果「50 fps」で書き出したファイルが 10 fps、つまり 10 倍遅く動きます。これを無効にするフラグはありません。1 フレームの GIF を余白として敷き詰めていた時代からの制限で、いまもすべてのエンジンが適用しています。本ツールは宣言どおりの合計とブラウザでの実際の長さを併記するので、制限に当たっているファイルと元から長いファイルを見分けられます。速い動きが必要なら GIF ではなく動画コーデックを使ってください。
ループ回数は具体的に何を意味しますか。
ループは GIF 仕様には存在しません。1995 年に Netscape が追加したアプリケーション拡張で、11 バイトの識別子 NETSCAPE2.0 のあとに 16 ビットの回数を持つサブブロックが続きます。0 は無限で、ほとんどのエンコーダーはこれを書きます。0 以外は初回再生のあとに繰り返す回数なので、1 なら Chrome と Firefox では 2 回再生されますが、一部の古いビューアーは合計回数と解釈していました。ブロックがまったくない場合、アニメーションはちょうど 1 回再生されて最後のフレームで止まります。未知の拡張を捨てるツールを通したファイルでよく起きる驚きです。
GIF のサイズが大きすぎるのはなぜですか。
ほとんどの場合、各フレームが変化した部分ではなく画面全体を保存しているからです。ここでのバイト列は、グラフィック制御拡張、画像記述子、ローカルカラーテーブル、LZW データまでフレームの費用をすべて合算するため、順位は推定ではなく正確です。効くのは 3 つです。毎フレームが論理画面と同じ大きさの全画面書き換え、256 項目で 1 つ 768 バイトのローカルカラーテーブル(60 フレームなら画素を入れる前に 45 KB)、そして写真やディザ画像で元のインデックスより大きくなりうる LZW そのものです。バイトの内訳がこの 3 つを分けて示します。
廃棄方法とは何で、なぜ残像が出るのですか。
GIF のフレームは前のフレームが残したキャンバスの上に描かれます。廃棄方法は、次のフレームを描く前にそのフレームをどう扱うかを決めます。0(指定なし)と 1(そのまま)は残すので、変わった画素だけを保存する差分フレームが可能になります。2 はフレームの矩形を背景に戻します。透過画素を積み重ねたくないときに必要ですが、毎回全画面を消すとちらつきが見えます。3 は描く前の状態に戻すもので、費用が高く実装も一定しません。尾を引く残像は、2 を使うべきところで 1 を使ったか、一度も消されていない画面の上に透過画素を重ねた場合がほとんどです。
透過の縁がギザギザに見えるのはなぜですか。
GIF の透過はアルファチャンネルではなく、パレットのインデックス 1 つです。フレームは 1 項目だけを透過に指定でき、そのインデックスを持つ画素は合成時に飛ばされます。完全な不透明と完全な透明の間には何もありません。PNG のアンチエイリアスされた縁は行き場がなく、書き出しツールが仮定した背景と混ざって白や灰色の縁になるか、透過インデックスに丸められて階段状になります。色も 1 つ消費します。透過のある画像で使えるのは 256 色ではなく 255 色です。透過インデックスはフレームごとなので、デコーダーは常に現在のフレームの値しか返しません。
GIF87a と GIF89a の違いは何で、インターレースは今も役に立ちますか。
GIF87a は 1987 年の原型で、拡張ブロックがまったくありません。つまり遅延も透過もループカウンターもコメントもありません。GIF89a が拡張の仕組みを加え、私たちが GIF らしさと思うものはすべてそこにあります。どちらも今もあらゆる環境で読め、89a 固有の機能が要らないときにエンコーダーが 87a を書くのは妥当です。静止画 1 枚ならたいていそうなります。インターレースはフレームごとの別のフラグで、行を 4 回に分けて保存し、途中まで受信した段階で絵全体の粗い姿を見せます。現代の回線では得るものがなく、隣り合う行の相関を断ち切るぶん LZW ストリームはむしろ少し大きくなります。インターレースされたフレームは、古いツールを通ったファイルであることの目印くらいの意味です。

関連ツール

WebAssembly モジュールインスペクタ

ブラウザ内で .wasm を解析し、セクションのサイズ、型付きのインポートとエクスポート、メモリのページ数、start 関数、name と producers セクションを表示します。

開発 0 0

WebP ファイル検査ツール

.webp の RIFF チャンクをブラウザーで辿ります。非可逆・可逆・拡張の判別、キャンバスとフレームサイズの比較、アニメーションの時間、アルファ、ICC、Exif、XMP を表示します。

ファイル 0 0

MP4 / ISO ベースメディア構造インスペクター

MP4・M4A・M4V・MOV をブラウザーで解析。ブランド、ファストスタート判定、ボックスツリー、トラックごとのコーデックと長さ、iTunes タグを表示します。

ファイル 0 0

EditorConfig テスター

.editorconfig とファイルパスを貼り付けると、各ファイルに最終的に適用されるプロパティと、それを決めたセクションと行番号が分かります。

開発 0 0

gzip(.gz)インスペクター

.gz のヘッダーを項目ごとに読み、全メンバーをたどり、ブラウザ内で CRC32 と実サイズを再計算してトレーラーを検証します。

ファイル 0 0

JPEG構造インスペクター

JPEGのマーカーセグメントを順に確認できます。ベースラインかプログレッシブか、色差の間引き、推定品質、バイトの内訳まで。

画像 0 0