Animated PNG graphics

by 3 contributors:

作者

APNG 仕様は以下のメンバーによって作られました:

概要

APNGは Portable Network Graphics (PNG) フォーマットの拡張であり、アニメーション画像のサポートが追加されています。これは普及しているシンプルなアニメーション画像の GIF フォーマットに取って代わることを目的に作られたもので、GIF にはない 24 bit イメージや 8 bit の透明色を扱うことができます。 APNG は MNG の簡潔な代替案であり、インターネットで一般的に使用されるアニメーション画像に適した仕様を規定します。

APNG は PNG の後方互換です。 PNG デコーダは APNG 仕様のチャンクを無視して静止画を表示します。

用語

デフォルト画像は標準の 'IDAT' チャンクに記述されます。これは APNG に対応していないデコーダが表示する画像です。

キャンバスは各フレームが表示される出力デバイスの領域です。キャンバスの内容はデコーダにとって有効である必要はありません。 PNG 仕様により、'bKGD' チャンクがあれば背景の指定が無くても 'bKGD' の色で塗りつぶされます。

出力バッファはピクセルの配列であり、PNG の 'IHDR' チャンクの幅と高さでサイズが決まります。概念的には、各フレームはキャンバスに描画する前に出力バッファ上に作成されます。出力バッファの内容はデコーダのために用意されます。出力バッファの角はキャンバスの角にマッピングされます。

完全に透過な黒とは RGB とアルファ値の全てが 0 の状態を指します。

チャンクの説明で使用される値について、unsigned int は 32 bit 符号なし整数であり、ネットワーク上のバイトオーダーで値は 0 から 2^31)-1 に制限されます。unsigned short は 16 bit 符号なし整数であり、ネットワーク上のバイトオーダーで値の範囲は 0 から (2^16)-1 です。byte は 8 bit 符号なし整数であり、0 から (2^8)-1です。

エラー処理

APNG はイメージ全体を読み込む前に、すでに読み込んであるフレームを順番に描画するようにデザインされています。この方法だと実際にアニメーションが始まるまで気付かないエラーも有り得えます。デコーダがエラーを発見した場合、以降のフレームを全て破棄し、アニメーションを止め、 デフォルト画像の表示に戻ることを強く推奨します。デコーダがアニメーションを始める前にエラーに気付いた場合、デフォルト画像を表示しなければなりません。それが妥当ならば、ユーザーにエラーメッセージが表示するのも良いでしょう。

構造

APNG のデータ構造の並びは PNG 仕様で定義されているただの PNG と同様です。3 種類のチャンクを追加することでアニメーションのフレームデータを規定します。

APNG と識別するには 'IDAT ' チャンクの前に 'acTL ' チャンクが存在しなければなりません。'acTL ' チャンクの構造は後で述べます。

概念的には、再生するたびに出力バッファは '完全に透過な黒 ' で初期化しなければなりません。初期化は 'IHDR ' チャンクで幅と高さを指定された矩形を完全に塗りつぶします。

デフォルト画像をアニメーションに含める場合、'IDAT ' チャンクの前に 1 つ 'fcTL ' チャンクを置いてください。そうすることで 'fcTL ' チャンクの中でデフォルト画像がアニメーションの 1 フレーム目であることを指定します。 そうしなかった場合、デフォルト画像はアニメーションに含まれません。

以降のフレームは 'fdAT ' チャンクの中にエンコードしておきます。'fdAT ' チャンクはシーケンス番号から始まっていること以外は 'IDAT ' と同様の構造です。 各フレームの場所とレンダリング情報は 'fcTL ' チャンクに格納します。'fdAT ' チャンクと 'fcTL ' チャンクの完全な構造は後で述べます。

アニメーション全体の境界は 'IHDR' チャンクの幅と高さで決まります。デフォルト画像がアニメーションに含まれているかは関係ありません。デフォルト画像以降のフレームで描画しない範囲がある場合、完全な透明色で適切にパディングするべきです。

それぞれのフレームは何度再生しても完全に一致します。これはアプリケーションが各フレームをキャッシュするための仕様です。

チャンクシーケンス番号

'fcTL' チャンクと 'fdAT' チャンクは 4 byte のシーケンス番号を持ちます。2 種類のチャンクはシーケンスを共有します。これには APNG のシーケンスエラーを確認し、同時にエラー情報を収集する狙いがあります。PNG の仕様では補助チャンクの順序に制限はありません。

最初の 'fcTL' チャンクはシーケンス番号が 0 でなければなりません。以降の 'fcTL' チャンクと 'fdAT' チャンクにおいて、シーケンス番号の欠番や重複があってはなりません。

下の表は 2 フレーム以上で 2 つ以上の 'fdAT' チャンクを持つ場合のシーケンス番号について表しています。

1 フレーム目がデフォルト画像の場合

シーケンス番号 チャンク
(none) 'acTL'
0 'fcTL'(1 フレーム目を指定)
(none) 'IDAT'(1 フレーム目で使う画像 / デフォルト画像)
1 'fcTL'(2 フレーム目を指定)
2 'fdAT'(2 フレーム目で使う画像のデータ 1)
3 'fdAT'(2 フレーム目で使う画像のデータ 2)
... ...

デフォルト画像をアニメーションで使わない場合

シーケンス番号 チャンク
(none) 'acTL'
(none) 'IDAT'(デフォルト画像)
0 'fcTL'(1 フレーム目を指定)
1 'fdAT'(1 フレーム目で使う画像のデータ 1)
2 'fdAT'(1 フレーム目で使う画像のデータ 2)
... ...

デコーダは順番を守らない APNG チャンクをエラーとして扱います。 APNG 対応の PNG エディタはシーケンス番号を正しく修正すべきです。

'acTL' : Animation Control チャンク

'acTL' チャンクは PNG 仕様の定義では補助チャンクです。それは正当な PNG の構造を守った上で、最初の 'IDAT' チャンクの前に存在しなければなりません。

'acTL' チャンクの内容は以下の通りです。

バイトオフセット フィールド名 フィールドの型 説明
0 num_frames unsigned int APNG のフレーム数
4 num_plays unsigned int APNG のループ回数。0 を指定すると無限ループ。

num_frames はアニメーションのトータルフレーム数を表します。これは 'fcTL' チャンクの数と一致しなければなりません。'num_frames' に 0 を指定してはなりません。1 フレームのみの APNG には 1 を指定します。この値が実際のフレーム数と異なる場合、エラーとして扱われるべきです。

num_plays はアニメーションが何回再生すべきかを表します。0 が指定された場合、永久に再生を続けます。0 以外が指定された場合、指定された回数を再生し、最後のフレームになったらアニメーションを停止します。

'fcTL': Frame Control チャンク

'fcTL' チャンクは PNG 仕様の定義では補助チャンクです。対象フレームの 'IDAT' チャンクまたは 'fdAT' チャンクの前に存在しなければなりません。具体的には、

  • デフォルト画像の場合、'fcTL' チャンクは 'IDAT' チャンクの前に存在しなければなりません。'acTL' と 'fcTL' の順番は定義していません。
  • デフォルト画像を除く最初の画像(1 フレーム目か 2 フレーム目の画像)の場合、'fcTL' チャンクは全ての 'IDAT' チャンクの後に存在しなければなりません。また、対応するフレームの 'fdAT' の前に存在しなければなりません。
  • 以降の全てのフレームについて、N フレーム目の 'fcTL' チャンクは N-1 フレーム目の 'fdAT' チャンクの後に存在しなければなりません。また、N フレーム目の 'fdAT' チャンクの前に存在しなければなりません。
  • その他の補助チャンクは APNG チャンクの間に存在してもかまいません。その中には 'fdAT' チャンクも含まれます。

それぞれのフレームに 1 つの 'fcTL' チャンクが必要です。

バイトオフセット フィールド名 フィールドの型 説明
0 sequence_number unsigned int アニメーションチャンクのシーケンス番号、0 から始まる
4 width unsigned int 後に続くフレームの幅
8 height unsigned int 後に続くフレームの高さ
12 x_offset unsigned int 後に続くフレームを描画する x 座標
16 y_offset unsigned int 後に続くフレームを描画する y 座標
20 delay_num unsigned short フレーム遅延の分子
22 delay_den unsigned short フレーム遅延の分母
24 dispose_op byte フレームを描画した後にフレーム領域を廃棄するか?
25 blend_op byte フレーム描画方法のタイプ

フレームは x_offsety_offsetwidthheight で定義された領域に描画します。 オフセットは負の値となってはなりません。 領域は正の値でなければなりません。 描画領域はデフォルト画像からはみ出てはいけません。

フレーム領域の制限は以下の通りです。

  • x_offset >= 0
  • y_offset >= 0
  • width > 0
  • height > 0
  • x_offset + width <= 'IHDR' width
  • y_offset + height <= 'IHDR' height

delay_numdelay_den で対象のフレームを何秒遅らせて表示するかを指定できます。分母 (denominator)に 0 を指定した場合、100 として扱います。 その場合、delay_num は 1/100 秒の遅延となります。 分子 (numerator)が 0 の場合、デコーダは次のフレームをできる限り速く描画しますが、ビューアの仕様で速さに制限をかけてもかまいません。

フレームのタイミングはデコードするタイミングと表示のタイミングの両方から独立していなければなりません。これはデコーダの実装によらず同じ速さでアニメーションを表示するためです。

dispose_op は遅延が終わった後、次のフレームをレンダリングする前に出力バッファをどうするか指定します。

dispose_op として有効な値は以下の通りです。

定数 説明
0 APNG_DISPOSE_OP_NONE 次のフレームを描画する前に消去しません。出力バッファをそのまま使用します。
1 APNG_DISPOSE_OP_BACKGROUND 次のフレームを描画する前に、出力バッファのフレーム領域を完全に透過な黒で塗りつぶします。
2 APNG_DISPOSE_OP_PREVIOUS 次のフレームを描画する前に、出力バッファのフレーム領域をこのフレームに入る前の状態に戻します。

最初の 'fcTL' チャンクの dispose_opAPNG_DISPOSE_OP_PREVIOUS が指定された場合、 APNG_DISPOSE_OP_BACKGROUND のときと同様に扱います。

blend_op は現在の出力バッファにアルファブレンドで合成するか、完全に出力バッファを入れ替えるかを指定します。

blend_op として有効な値は以下の通りです。

定数 説明
0 APNG_BLEND_OP_SOURCE アルファ値を含めた全ての要素をフレームの出力バッファ領域に上書きします。
1 APNG_BLEND_OP_OVER 書き込むデータのアルファ値を使って出力バッファに合成します。このとき、PNG 仕様 への拡張 Version 1.2.0アルファチャンネル処理 に書いてある通り上書き処理をします。サンプルコードの 2 つ目の項目を参照してください。

2 つのブレンドモードは最初のフレームでは同じ結果になることに注意してください。これはどちらのブレンドモードでも出力バッファが初期化されているためです。

デフォルト画像に対する 'fcTL' チャンクには、以下の制限があります。

  • x_offsety_offset は 0 でなければなりません。
  • widthheightIHDR で指定された値と等しくなければなりません。

まず注意すべきなのは、どのように再生する場合でも出力バッファは完全に透過な黒で初期化するということです。これはどのように再生する場合でもアニメーションが一致することを保証します。デコーダは、結果が一致すると保証できる場合には初期化ステップを省略することができます。例えば、デフォルト画像がアニメーションに含まれており、blend_opAPNG_BLEND_OP_SOURCE が設定されている場合は初期化は不要です。この場合、出力バッファが完全に上書きされるからです。

'fdAT': Frame Data チャンク

'fdAT' チャンクは 'IDAT' チャンクと同じ目的のデータです。'fdAT' チャンクはシーケンス番号から始まっていること以外は 'IDAT' と同様の構造です。

各フレームには少なくとも 1 つの 'fdAT' チャンクが存在しなくてはなりません。フレーム内にある 'fdAT' チャンクの全てのデータフィールドを連結すると、圧縮された画像データになります。画像データストリームを解凍すると、PNG 画像の完全なピクセルデータになります。解凍されたデータストリームは、スキャンライン毎の開始点のフィルターバイトを含み、解凍された 'IDAT' チャンクのデータと同様です。それはデフォルト画像と同様に、'IDAT' チャンクと同じビット深度、カラータイプ、圧縮方式、フィルター方式、インタレース方式ともしあるならばパレットを利用します。

フォーマットは以下の通りです。

バイトオフセット フィールド名 フィールドの型 説明
0 sequence_number unsigned int アニメーションチャンクのシーケンス番号、0 から始まる。
4 frame_data X bytes このフレームのデータ。

それぞれのフレームはファイルの最初の 'IDAT' チャンク以前にある必須チャンクまたは補助チャンクの指定を継承します。ただし、幅と高さは 'fcTL' チャンクの値を使用します。

'pHYs' チャンクが存在する場合、APNGの x_offsety_offset はデフォルト画像と同様にスケーリングしなければなりません。概念的には、このようなスケーリングは出力バッファをキャンバスにマッピングするときに発生します。

この仕様の更新履歴

From 0.1

  • anIM' 及び 'frAm' を PNG 仕様のチャンク命名規則に対応するように名前を変更。
  • セクション 2 において APNG 構造のより詳細な説明を追加。
  • セクション 3.2 において png の他のチャンクとの相互作用についての情報を追加。
  • 'frAm' チャンクオフセットと符号付き整数への遅延を変更。

From 0.2

  • MNG 'FRAM' チャンクとの衝突を避けるために 'frAm' チャンクを 'afRa' に変更。
  • フォーマットの変更:IHDR..IDAT..IEND シーケンスの代わりに、0 ではないフレームが 'afRa' チャンクに保持されるように。
  • アニメーションを開始すべきフレームを示すために start_frame を 'anIm' に追加。
  • 'anIm' チャンクから num_frames を削除。

From 0.3

  • 最近の png-list discussion より 'aCTL', 'fdAT', 'fcTL' の説明を追加。
  • グローバル及びローカルのパレットと透過について説明した、セクション 4「他の PNG チャンクとの相互作用」を追加。
  • より一般的なチャンクを参照するための 'oFFs' チャンクセクションを変更。
  • すべてのフレームは互いにシングルチャンクでなければならない、あるいは、最初のチャンクは空データを持たなければならないことを示すために 'aDAT' の説明を更新。
  • 各フレームの範囲 (x, y, width, height) は完全に親 PNG キャンバス以内に無ければならないという注意を追加。
  • dispose_op の説明を修正(前ではなく、後)
  • dispose_oprender_op に変更。disposal の説明を追加、BLEND フラグの説明を追加。
  • ミリ秒の整数にならない遅延を指定するために delay_time を 遅延分子と分母に変更。
  • パレットアニメーションはサポートされていないことを明らかにするための注記を追加。
  • aCTL から start_frame を削除。フレーム 0 には fcTL が必要。 SKIP_FRAME fCTL フラグを追加。

From 0.4

  • num_frames を aCTL に再導入。
  • sequence_number を aDAT から fCTL に移動。
  • aDAT の内容を fCTL+IDATs+fEND に変更。
  • 何が許可されて、何が許可されないかの明示を追加。
  • PNG 仕様のチャンク命名規則に従うために aCTL を acTL に、fCTL を fcTL に、aDAT を fdAT に、fEND を feND に名称変更。

From 0.5

  • IHDR と PLTE CRCs を acTl チャンクに追加。
  • acTL fcTL 及び adAT をコピーセーフに。これらを acTl, fcTl 及び adAt に名称変更。

From 0.6

  • fdAt チャンクを他のチャンクのコンテナではなく、IDAT チャンクの代替に変更。
  • feND チャンクを削除。
  • シーケンスナンバーフィールドを fdAt に追加。
  • fcTl において widthheight フィールドを再導入。

From 0.7

  • hidden を削除。代わりに、最初のフレームだけを隠すことができ、それは fcTl の欠如で示すように。
  • IDAT、fcTl 及び fdAt がそれらの間に他のチャンクを持つ必要がないように変更。

From 0.8

  • acTl から IHDR and PLTE のための CRCs を削除。
  • acTL fcTL and adAT はコピーセーフではなくなり、それらを acTL, fcTL 及び adAT に変更。

From 0.9

render_opdispose_opblend_op に分離。

From 0.10

  • 変更無し

テストエンコーダーとサンプル画像

サンプル画像は http://littlesvr.ca/apng/ の APNG 実装ページにあります。

オープンソースのエンコーダーは 1.9 alpha 4 以降の Gecko エンジン にあります。

Mozillaの APNG エンコーダーを組み込んだオープンソースのアプリケーションはこちらにあります。 http://littlesvr.ca/apng/apngedit.html

関連情報

ドキュメントのタグと貢献者

タグ: 
Contributors to this page: ethertank, Potappo, Mgjbot
最終更新者: ethertank,