GIF(Graphics Interchange Format)是由 CompuServe 于 1987 年推出的图像格式,广泛用于简单动画和低色彩图像。其文件结构基于块(Blocks)组织,支持调色板(Palette) 、透明色 和多帧动画。

一、总体结构
一个 GIF 文件由以下主要部分组成:
+---------------------+
| Header | ← 标识 GIF 版本
+---------------------+
| Logical Screen Descriptor | ← 全局画布信息
+---------------------+
| Global Color Table | ← 可选,全局调色板
+---------------------+
| Data Blocks | ← 图像数据或扩展块(可多个)
| ├── Graphic Control Extension (GCE) ← 动画/透明控制
| ├── Image Descriptor + Local Color Table + Image Data
| ├── Comment Extension
| ├── Plain Text Extension(已废弃)
| └── Application Extension(如 Netscape 动画循环)
+---------------------+
| Trailer | ← 文件结束标记(0x3B)
+---------------------+
所有多字节整数均采用 小端序(Little-endian)
二、详细组成部分
1. Header(6 字节)
| 偏移 | 内容 | 说明 |
|---|---|---|
| 0--2 | "GIF" |
固定 ASCII 字符串 |
| 3--5 | 版本号 | 通常是 "87a" 或 "89a" |
- GIF87a:原始版本,不支持动画、透明等
- GIF89a :增强版,支持:
- 透明色(Transparent Color)
- 动画(通过 Application Extension)
- 注释、文本等扩展块
现代 GIF 几乎都是 GIF89a
2. Logical Screen Descriptor(7 字节)
描述整个 GIF 的"逻辑屏幕"(即画布)大小和全局属性:
| 字节 | 长度 | 说明 |
|---|---|---|
| 0--1 | Width | 画布宽度(像素) |
| 2--3 | Height | 画布高度(像素) |
| 4 | Packed Fields | 位字段(见下表) |
| 5 | Background Color Index | 背景色在全局调色板中的索引 |
| 6 | Pixel Aspect Ratio | 像素宽高比(通常为 0,表示无指定) |
Packed Fields(第 4 字节):
| 位 | 含义 |
|---|---|
| 7 | Global Color Table Flag(1 = 存在全局调色板) |
| 6--4 | Color Resolution(颜色分辨率,实际很少用) |
| 3 | Sort Flag(调色板是否按重要性排序,通常为 0) |
| 2--0 | Size of Global Color Table(N,调色板大小 = 2^(N+1)) |
例如:若该字节为
0b10010001→
- 有全局调色板(bit 7 = 1)
- Size = 1 → 调色板条目数 = 2^(1+1) = 4
3. Global Color Table(可选)
- 若 Global Color Table Flag = 1,则紧跟在此处
- 每个颜色占 3 字节(RGB,各 1 字节)
- 总长度 =
3 × 2^(N+1)字节
示例:若 N=2 → 调色板有 8 个颜色 → 占 24 字节
4. Data Blocks(主体内容,可重复)
每个块以一个 Block Type(1 字节) 开头:
| Block Type (Hex) | 类型 | 说明 |
|---|---|---|
0x2C |
Image Descriptor | 图像帧数据开始 |
0x21 |
Extension Introducer | 扩展块开始(后面跟标签) |
0x3B |
Trailer | 文件结束 |
A. Extension Blocks(以 0x21 开头)
格式:
21 [Label] [BlockSize] [Data...] [0x00]
常见 Label:
| Label (Hex) | 名称 | 用途 |
|---|---|---|
0xF9 |
Graphic Control Extension (GCE) | 控制帧延迟、透明色、处置方式 |
0xFE |
Comment Extension | 注释(可含任意文本) |
0x01 |
Plain Text Extension | 已废弃 |
0xFF |
Application Extension | 如 Netscape 动画循环 |
▶ Graphic Control Extension(GCE,最常用)
- 长度固定为 4 字节数据 + 1 字节块结束(0x00)
- 结构:
| 字节 | 说明 |
|---|---|
| 0 | Block Size(通常为 4) |
| 1 | Packed Fields(含透明、处置方式) |
| 2--3 | Delay Time(帧持续时间,单位 1/100 秒) |
| 4 | Transparent Color Index(透明色索引) |
| 5 | Block Terminator (0x00) |
Packed Fields(第 1 字节):
| 位 | 含义 |
|---|---|
| 7--6 | Disposal Method(帧后处理方式) |
| 5 | User Input Flag(是否等待用户输入,几乎不用) |
| 4 | Transparent Color Flag(1 = 启用透明色) |
| 3--0 | 保留(必须为 0) |
Disposal Method 常见值:
0或1:不清除,直接绘制下一帧(叠加)2:恢复为背景色3:恢复为前一帧(用于擦除动画)
▶ Application Extension(动画循环)
-
用于指定 GIF 循环次数(Netscape 标准)
-
典型结构:
21 FF 0B
4E 45 54 53 43 41 50 45 20 32 2E 30 ← "NETSCAPE2.0"
03
01
[LO][HI] ← 循环次数(0 = 无限循环)
00
注意:
[LO][HI]是小端序的 2 字节整数
B. Image Descriptor(0x2C)
每帧图像的开始:
| 字节偏移 | 长度 | 说明 |
|---|---|---|
| 0 | 1 | 0x2C |
| 1--2 | 2 | Left(图像左上角 X 坐标) |
| 3--4 | 2 | Top(Y 坐标) |
| 5--6 | 2 | Width |
| 7--8 | 2 | Height |
| 9 | 1 | Packed Fields |
Packed Fields(第 9 字节):
| 位 | 含义 |
|---|---|
| 7 | Local Color Table Flag(1 = 使用局部调色板) |
| 6 | Interlace Flag(1 = 隔行扫描) |
| 5 | Sort Flag(局部调色板是否排序) |
| 4--0 | Size of Local Color Table(N,条目数 = 2^(N+1)) |
如果 Local Color Table Flag = 1,则紧跟 局部调色板(格式同全局)
C. Image Data(LZW 压缩)
紧跟在 Image Descriptor(和局部调色板,如果有)之后:
- 第 1 字节:LZW Minimum Code Size(通常为颜色深度,如 8 色 → 3)
- 后续为 子块(Sub-blocks) :
- 每个子块:1 字节长度(1--255)+ 数据
- 以 长度为 0 的子块 (
0x00)结束
GIF 使用 LZW(Lempel-Ziv-Welch) 压缩算法,但对原始 LZW 做了修改(如 Clear Code、End Code 等)
5. Trailer(1 字节)
- 固定值:
0x3B - 表示文件结束
三、典型 GIF 文件结构(动画示例)
text
GIF89a
Logical Screen Descriptor
Global Color Table (256 colors)
Application Extension: NETSCAPE2.0 (loop forever)
Graphic Control Extension (delay=100, transparent index=0)
Image Descriptor (frame 1 at 0,0)
Image Data (LZW compressed)
Graphic Control Extension (delay=100, transparent index=0)
Image Descriptor (frame 2 at 0,0)
Image Data
...
Trailer (0x3B)
四、关键限制与特点
| 特性 | 说明 |
|---|---|
| 颜色数 | 最多 256 色(8-bit 索引) |
| 透明 | 仅支持单色透明(一个索引值) |
| 动画 | 通过多帧 + GCE + Application Extension 实现 |
| 压缩 | LZW(无损) |
| 最大尺寸 | 每帧 ≤ 65535×65535,但实际受浏览器限制 |
| 隔行扫描 | 支持(Interlace),用于渐进显示 |
五、参考资料
- GIF89a 官方规范:https://www.w3.org/Graphics/GIF/spec-gif89a.txt
- 工具:
gifsicle(可解析/优化 GIF)、xxd(十六进制查看)
如需深入了解 LZW 解码过程 、动画帧合成逻辑 或 如何手动构造 GIF,我可以进一步展开说明。