· 1 min read

GIFを実際に動作させる方法 — キャンバスフレームからLZW圧縮まで

GIF フォーマットは 39 歳でありながらどこでも。 'Export' をクリックしてファイルを取得すると、フレームキャプチャ、カラー定量化、LZW 圧縮、および GIF が 4MB である理由の間に何が起こるかを示します.

GIFがまだ存在している理由

グラフィック・インターチェンジ・フォーマットは、1987年にCompuServeによって作成されました。 アニメーション、透明度、ロスレス圧縮に対応しています。 1フレームあたり256色に制限されます。 音声はありません。 大きいファイルを作成します。 すべての技術的な測定によって、それは10年前に取り替えられたべきです.

そして、まだ:Discord、Slack、iMessage、Twitter、Reddit、およびすべてのサポートGIFをネイティブにメールします。 GIPHY は 1 日あたりの 10 億のGIF を扱います [GIPHY, 2020]. どこでも動作するので、コーデックが不要で、自動的に再生します。 他のフォーマットに普遍的なサポートおよびゼロ フリクションのプレーバックのこの組合せがありません.

GIFがトリビアを超えてどのように役立つかを理解する — エクスポートしたGIFが4MB、なぜグラデーションがバンドルされているのか、そしてそれについてできることを説明しています.

ステップ1:フレームキャプチャ

アニメーションGIFは、各間の遅延で表示されている画像(フレーム)のシーケンスです。 キャンバスアニメーションから1つを作成するには、通常の間隔でキャンバスの状態をキャプチャする必要があります.

ブラウザでは、通常はcanvas.toDataURL()またはctx.getImageData()を介して、各フレーム時間のHTMLQ0Q要素からピクセルデータを読み込みます。 ターゲットタイムにアニメーションが進んでおり、キャンバスがレンダリングされ、ピクセルがキャプチャされます。 重要な制約: ピクセルを読み取り前にブラウザのペイントサイクル(requestAnimationFrame)を待つ必要があります。それ以外の場合は、ストールバッファをキャプチャします.

典型的なGIFは3秒間15のFPSで45フレームの捕獲を要求します。 1080×1080の解像度では、各フレームが約4.7万画素です.

ステップ2:色定量化

GIFは、カラーテーブル(パレット)に格納されたフレームあたり最大256色をサポートしています。 典型的なキャンバスフレームは、何千もの異なる色を持っています。 目に見える分解なしで256に減らすことはGIFの符号化の最も困難な部分です.

標準アプローチは、medianカットアルゴリズム[Heckbert, 1982]です。すべてのピクセルをReddestチャンネルでソートし、リストをメディアンに分割し、緑色と青を繰り返し、色空間を256地域に再帰的に分割します。 各地域の平均はパレットエントリになります。 これは gif.js — ライブラリ PinePaper が使用している — 並列 [Rubaxa, gif.js] の Web ワーカーで実装します.

色の量子化は、GIFがフラットカラーのグラフィックをうまく処理する理由ですが、写真やグラデーションに苦労しています。 1080ピクセルを越えたグラデーションは500以上の異なる色を使うかもしれません。 256 に圧縮すると、可視バンキングが生成されます。勾配が滑らかになるべきでないステップです.

それについてできること: あなたの設計の少数の色を使用して下さい。 平らな形状、固形、およびテキストはよく定量化します。 スムーズなグラデーションと写真のテクスチャーはしません。 あなたのGIFがバンディングを持っている場合は、パレットを簡素化し、解像度ではありません.

ステップ3:LZW圧縮

※Lempel-Ziv-Welch** (LZW) 圧縮(Welch, 1984) で各フレームのピクセルインデックス(256色のパレットへの参照)を圧縮します。 LZW は、データをスキャンする際に繰り返されたバイトシーケンスの辞書を作成します。 以前に見たシーケンスに遭遇すると、生バイトの代わりに辞書インデックスが出力されます.

これは、繰り返された色の大きな領域があるときにGIFの圧縮が最も効果的であることを意味します - 固体背景、フラットな形状、均一な表面上のテキスト。 LZW辞書は数回繰り返されたシーケンスを見つけるので、ピクセルレベルのバリエーションを持つ複雑なテクスチャは、低圧縮比を生成します.

実用的影響: 黒い背景の白いテキストの1080×1080 GIFは200KBに圧縮するかもしれません。 複雑な写真の同じ解像度GIFは8MBになる可能性があります。 ファイルのサイズは、解像度やフレーム数よりも視覚的な複雑さに依存します.

ステップ4:フレーム処分と最適化

GIFフレームはdisposalメソッドを指定できます。次のフレームを描画する前にキャンバスをクリアするか、前のフレームを非表示にするか、または 背景。 スマートGIFエンコーダは、フレーム間で変更されたピクセルだけをエンコーディングするフレームの異なる**を使用しています.

アニメーションが小さな移動要素で静的な背景を持っている場合、最適化されたGIFは背景を一度エンコードし、要素が移動した領域だけを更新します。 これによりファイルサイズが劇的に低下します。 PinePaperのエンコーダは、この最適化を自動的に適用するgif.jsを使用します.

数字

典型的なPinePaperアニメーション(1080×1080、15 FPS、3秒、アニメーションテキストの暗い背景):

コンポーネント サイズ:
生フレーム(45×4.7Mピクセル×3バイト) ~634 MB
量子化後(256色、1バイト/ピクセル) ~211 MB
LZW圧縮後 ~2-4 MB
フレームの相違を使って ~1-2 MB

生から最終までの圧縮率は約300:1〜600:1です。 このほとんどは、色定量(3:1)とLZW(50:1〜100:1)から来ます.

GIFと他のフォーマットを使用するとき

フォーマット 最高の 制限事項
GIFの ユニバーサルサポート、自動再生、メッセージングアプリ 256色、大きいファイル、音声無し
WebM (VP9) 最高の品質、最小ファイル、Web Safari、iMessageの限定サポート
MP4 (H.264) ソーシャルメディア、ビデオプレーヤー コーデック、透明性なし
ツイート 透明度の高いフルカラーアニメーション 古いブラウザでの限定サポート

GIFは普遍的な両立性および自動演劇を必要とするとき正しい選択です。 質かファイル サイズのために、WebMかMP4はよりよいです.

お問い合わせ

PinePaper Studioを開き、設計を作成し、GIFとしてエクスポートします。 ファイルのサイズが変更されるかを観察します

  • フレームのカウントを増加して下さい(より多くのフレーム=より大きいファイル、比例して)
  • グラデーションを追加 (poor 量子化 = 大きいファイル)
  • ソリッドカラー(良好な量子化=小さいファイル)を使用する
  • キャンバスサイズを増加(フレームごとのピクセル=より大きいファイル)

各変更は圧縮パイプラインの測定です。 あなただけのGIFを作るだけでなく、あなたの設計に情報理論が適用する方法を観察しています.

参考文献

  • コンピューサーブ (1987). グラフィック交換フォーマット仕様、バージョン87a.
  • GIPHY(2020年)。 GIPHY年次報告書: 10億人の毎日のサーブ.
  • Heckbert, P. (1982). フレームの緩衝表示のための色のイメージの量化。コンピュータ グラフィックス(SIGGRAPH)、16(3)、297-307.
  • Rubaxa. gif.js — ウェブワーカーを使った JavaScript GIF エンコーダー。 github.com/jnordberg/gif.js.js を github.com/jnordberg/gif.js にインストールします.
  • Welch、T.A.(1984)。 高性能データ圧縮技術 ※IEEE Computer*、17(6)、8-19.

PinePaperのGIFの輸出は自由です–透かし無し、印無し。 pinepaper.studio/editorを開き、最初のアニメーションをエクスポートします.

Ready to create?

Start making animated GIFs, videos, and graphics — free, no signup.

Open PinePaper Editor