gifuct-js

ブラウザやDeno環境でGIFファイルを解析・レンダリングするためのシンプルなJavaScript GIFデコーダーです。

デモ

ライブラリの動作を確認できます: ライブデモ

例として使用されているGIF a01-kanta.gif福井市動物園オープンデータ から取得したものです。

特徴

使い方

このライブラリはESモジュールとして配布されており、URLから直接インポート可能です。インストール手順は必要ありません。

GIFのデコード

GIFをデコードするには、ArrayBuffer として取得した後、parseGIFdecompressFrames 関数を使用します。

import { parseGIF, decompressFrames } from 'https://code4fukui.github.io/gifuct-js/src/index.js';

// GIFファイルを取得
const response = await fetch('path/to/your.gif');
const buffer = await response.arrayBuffer();

// GIFを解析
const gif = parseGIF(buffer);

// GIFフレームを展開
const frames = decompressFrames(gif, true); // true を指定するとキャンバス描画用のパッチが生成されます

フレームのレンダリング

frames 配列には、アニメーションをレンダリングするために必要なすべてのデータが含まれています。各フレームは、disposalType に従って前のフレームの出力の上に描画されるべきパッチです。

推奨されるレンダリング方法は、2つのキャンバスを使用することです。1つはGIF画像全体を合成するための非表示キャンバス、もう1つはそれを表示するための可視キャンバスです。

const canvas = document.querySelector('#player');
const ctx = canvas.getContext('2d');

// キャンバスのサイズを設定
canvas.width = gif.lsd.width;
canvas.height = gif.lsd.height;

// 合成用の一時キャンバスを作成
const tempCanvas = document.createElement('canvas');
const tempCtx = tempCanvas.getContext('2d');
tempCanvas.width = canvas.width;
tempCanvas.height = canvas.height;

let frameIndex = 0;

function draw() {
  const frame = frames[frameIndex];
  const { dims, patch, disposalType } = frame;

  // 方法2: 新しいパッチを一時キャンバスに描画し、
  // その後、一時キャンバスをメインキャンバスに描画します。
  if (disposalType === 2) {
    tempCtx.clearRect(0, 0, tempCanvas.width, tempCanvas.height);
  }

  // パッチからImageDataオブジェクトを作成
  const imageData = tempCtx.createImageData(dims.width, dims.height);
  imageData.data.set(patch);
  
  // パッチを一時キャンバスに描画
  tempCtx.putImageData(imageData, dims.left, dims.top);

  // 一時キャンバスを可視キャンバスにコピー
  ctx.drawImage(tempCanvas, 0, 0);

  // 次のフレームをスケジュール
  frameIndex = (frameIndex + 1) % frames.length;
  setTimeout(draw, frame.delay);
}

draw();

API

関数

parseGIF(arrayBuffer)

GIFの上位構造(ヘッダ、カラーテーブル、生のフレームデータなど)を解析します。この関数は画像データの展開は行いません。

decompressFrames(parsedGif, buildImagePatches)

データ構造

ParsedFrame

decompressFrames が返す配列の各オブジェクトは以下の構造を持ちます:

ライセンス

MIT License — LICENSE を参照してください。