# gifa **Repository Path**: devoink/gifa ## Basic Information - **Project Name**: gifa - **Description**: A GIF toolkit focused on frame decoding and composition, with extensible playback, frame extraction, and compression utilities. - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-19 - **Last Updated**: 2026-01-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # gifa gifa:一个 GIF 工具箱,核心是 GIF 帧解析与合成,并在此基础上扩展播放、抽帧与压缩等能力。 ## 功能特性 - ✅ 完整的 GIF 格式解析(GIF87a 和 GIF89a) - ✅ 支持单帧和多帧 GIF - ✅ LZW 解压算法实现 - ✅ 交错图像处理 - ✅ 透明色支持 - ✅ 动画帧提取(延迟时间、循环次数、处置方式) - ✅ 全局和局部调色板支持 - ✅ 注释和扩展数据提取 - ✅ 输出每一帧的“完整画面” RGBA(`fullRgbaData`,可直接渲染/导出) ## 环境支持 - ✅ Node.js - ✅ 浏览器(ESM / ` ``` ### Demo 项目内置了一个最小 demo:`demo/index.html`(上传 GIF、`GifPlayer` 播放控制、滑块切帧、渲染 `fullRgbaData`)。 ### 播放控制(跨端) `GifPlayer` 只依赖 `setTimeout`,可以在浏览器 / uniapp / 小程序 / Node 端使用。你只需要提供 `onRender` 回调决定“如何渲染一帧”。 ```ts import { GifParser, GifPlayer } from 'gifa'; const parser = new GifParser(uint8Array); const frames = parser.getFrames(); const player = new GifPlayer(frames, { loop: 'infinite', speed: 1, onRender: (frame, index) => { // 在这里把 frame.fullRgbaData 画到 canvas / 推给 WebGL / 导出等 // console.log('render', index, frame.fullRgbaData.length); } }); player.play(); // player.pause(); // player.seek(10); ``` ## Roadmap(计划开发) 以“帧级解码/合成”为核心,逐步补齐常见 GIF 工具能力: - [ ] **浏览器播放器**:绑定 `canvas`,支持 `play/pause/seek/speed/loop`,并支持事件回调 - [ ] **抽帧**:导出指定帧为 PNG(浏览器 Blob / Node Buffer) - [ ] **压缩**:尺寸缩放、降帧率、调色板量化(质量/体积权衡可配置) - [ ] **裁剪/缩放**:按 ROI 裁剪、按目标尺寸缩放 - [ ] **信息分析**:统计透明像素比例、变化区域、帧矩形分布等 - [ ] **流式/增量 API**:大 GIF 逐帧产出,降低内存占用 ## `rgbaData` vs `fullRgbaData` - **`fullRgbaData`(必有,推荐)**:每帧“完整画布”的 RGBA,尺寸恒为 `screen.width * screen.height * 4`,已按透明索引与处置方式完成帧合成,可直接渲染/导出。 - **`rgbaData`(可选)**:帧自身图像块(可能是局部矩形)的 RGBA,尺寸为 `descriptor.width * descriptor.height * 4`,不包含画布位置信息的展开,也不包含与前一帧的合成结果;适合做增量渲染或自行实现合成器。 ## API(核心) ### GifParser 主解析器类。 #### 构造函数 ```typescript constructor(data: Uint8Array, options?: { onWarning?: (message: string) => void }) ``` - `data`: GIF 文件的二进制数据(Uint8Array) - `options.onWarning`: 非致命问题回调(默认静默) #### 方法 ##### `parse(): GifData` 解析整个 GIF 文件,返回完整的 GIF 数据结构。 ##### `getFrames(): Frame[]` 获取所有帧的数组。 ##### `getFrameFullRgbaData(frameIndex: number): Uint8Array` 获取指定帧的“整帧画面” RGBA 数据(与 `frames[frameIndex].fullRgbaData` 等价)。 ##### `getMetadata()` 获取 GIF 的元数据: - `width`: 画布宽度 - `height`: 画布高度 - `frameCount`: 帧数 - `loopCount`: 循环次数(undefined 表示无限循环) - `hasGlobalColorTable`: 是否有全局调色板 - `globalColorTableSize`: 全局调色板大小 ### 类型定义 #### GifData 完整的 GIF 数据结构: ```typescript interface GifData { header: GifHeader; screenDescriptor: LogicalScreenDescriptor; globalColorTable?: ColorTable; frames: Frame[]; loopCount?: number; comments?: string[]; } ``` #### Frame 帧数据: ```typescript interface Frame { descriptor: ImageDescriptor; graphicControl?: GraphicControlExtension; pixels: number[][]; // 像素索引数组(二维) rgbaData?: Uint8Array; // 帧自身图像块(可能为局部矩形)的 RGBA fullRgbaData: Uint8Array; // 每帧完整画布的 RGBA(推荐用于渲染/导出) } ``` ## 开发 ```bash # 安装依赖 npm install # 编译 npm run build # 开发模式(监听文件变化) npm run dev ``` ## 许可证 MIT