引言
生活中有两个场景需要制作动图:产品动态功能演示
和动图表情包制作
。
从制作角度出发,制作一张GIF动图,主要分三个步骤:
- 录制:以特定帧率对区域画面进行采样
- 编辑:对采样片段进行剪辑
- 压缩:对导出内容进行压缩,不压缩文件可能会很大,容易造成PPT卡顿或超过传播平台大小限制
现有软件往往无法完全兼顾这三点,比如:
- ScreenToGif:集成了GIF录制和编辑功能,但对压缩功能的支持有所不足,且软件的操作较复杂,初学者上手存在一定学习成本。
- ShareX:支持GIF的区域录制,但录制往往存在启动帧冗余,往往需要对结果进行二次编辑。
- Adobe Premiere Pro(Pr):强大的视频编辑软件,支持将视频转成GIF格式,但导出格式容易让人误解,同时存在"GIF"和"GIF动画",如果选择GIF,竟然是将所有帧图像一张张单独导出来,很多人可能都踩过这个坑。

因此,我做了FreeGIF这个软件,它不仅能一次性解决这三个步骤,而且操作简单易上手。

FreeGIF 开源地址:https://github.com/zstar1003/FreeGIF
windows安装包:https://github.com/zstar1003/FreeGIF/releases/download/v1.0.0/FreeGIF.Setup.1.0.0.exe
mac安装包(arm)::https://github.com/zstar1003/FreeGIF/releases/download/v1.0.0/FreeGIF-1.0.0-arm64.dmg
mac安装包(x86):https://github.com/zstar1003/FreeGIF/releases/download/v1.0.0/FreeGIF-1.0.0.dmg
FreeGIF 使用方式
FreeGIF支持两种数据输入方式:
- 截屏录制:对屏幕区域进行截取录制
- 文件导入:直接导入已有的GIF文件
具体的使用方式参见以下视频:
FreeGIF:最简单的GIF动图制作软件
GIF压缩的底层逻辑
在此节中,将进一步探究GIF格式的本质,对底层感兴趣的读者可进一步阅读。
1. GIF文件结构
GIF (Graphics Interchange Format) 是诞生于1987年的一种位图图像格式。
一个 GIF 文件包含以下主要部分:
┌─────────────────────────┐
│ GIF Header (GIF89a) │ 6 字节
├─────────────────────────┤
│ Logical Screen Desc. │ 7 字节 - 屏幕尺寸、颜色信息
├─────────────────────────┤
│ Global Color Table │ 可选 - 最多 256 色调色板
├─────────────────────────┤
│ Application Extension │ 可选 - 循环次数等
├─────────────────────────┤
│ ┌───────────────────┐ │
│ │ Frame 1 │ │
│ │ - GCE Extension │ │ 延迟时间、透明色
│ │ - Image Desc. │ │ 帧位置、尺寸
│ │ - Local Color Tbl │ │ 可选局部调色板
│ │ - Image Data (LZW)│ │ 压缩的像素数据
│ └───────────────────┘ │
│ ┌───────────────────┐ │
│ │ Frame 2 ... │ │
│ └───────────────────┘ │
├─────────────────────────┤
│ GIF Trailer (0x3B) │ 1 字节
└─────────────────────────┘

2. GIF和MP4的区别
相同信息量的片段,为什么GIF文件会比视频MP4文件体积上大很多呢?
主要原因是GIF采用的压缩方法很落后,它是将每帧都完整存起来,而不是像视频那样只保留帧变化的部分。
GIF 采用的是 LZW (Lempel-Ziv-Welch) 无损压缩算法,LZW 是一种基于"字典"的无损压缩算法,通过"记忆"之前出现过的字节序列,用更短的"代码"替换它们,从而减少数据体积,压缩效果比较有限。
此外,由于历史原因,GIF 只支持最多 256 色(8-bit)的颜色空间,而MP4视频采用的是真彩色(24-bit,RGB每个通道都是8位),因此GIF颜色表现也远不如视频。
但是,GIF由于出现的比较早,所以基本所有的信息传输媒介都支持这种格式,并且,其不需要像视频那样需要解码器,支持在所有版本的PPT里播放。
目前,虽然有一些其它更好的动图格式出现,但由于历史原因,GIF仍然是目前使用最为广泛的动图格式。
3. GIF压缩方法
有些平台对GIF文件有限制,太大的根本发不出去,因此需要对GIF进行进一步压缩。
具体而言,可以从以下角度进行考虑:
1. 帧率
帧率是指一秒钟采样多少帧,在软件中,在录制前就可以进行设置,10FPS就代表每秒采样10帧。

通常的视频帧率是25FPS/30FPS,尽管高帧率会带来更好的流畅性,但文件体积也会显著增加,因此默认值是10FPS。
2. 分辨率
分辨率是指每帧画面的长宽像素值,在软件中,可以快速进行按比例进行下采样设置,具体有以下几档:

下调分辨率能够显著减小文件体积,但同时会使画面更模糊。
3. 颜色采样质量
由于GIF的每一帧只能包含最多 256 种颜色,因此制作GIF时,需要对真彩色图像(24-bit)进行采样。
颜色采样的本质是采用 NeuQuant 算法进行颜色量化,该算法是一种基于神经网络的算法:从图像中采样像素,训练 256 个神经元,调整最接近的神经元及其邻近神经元的颜色,最终,256 个神经元的颜色值即为最终调色板。
颜色采样质量越高,像素采样间隔越小,数据越丰富,最终的颜色会越接近真实值。
由于 GIF 采用 LZW 的压缩算法,当颜色较丰富时,压缩的空间会更小,因此颜色采样质量越高,文件体积也会相应较大。
4. 抖动处理
抖动处理是对颜色采样的后处理方式,当真彩色图像被限制到 256 色时,会产生明显的色带(banding)。
抖动处理解决的就是当像素颜色无法直接映射到调色板时,把误差分配给周围像素,让整体视觉更平滑。
误差指的是:原像素颜色−映射后的调色板颜色。
扩散范围是:这个误差可以传递到哪些周围像素、
在软件中,内置了四种抖动处理算法:

四种抖动算法的扩散范围和应用场景如下表所示:
算法 | 扩散范围 | 视觉效果 | 特点 / 适用场景 |
---|---|---|---|
Floyd-Steinberg | 当前像素 + 右1,下1左1,下1 | 细腻、噪点适中 | 最常用,均衡视觉质量和噪点,适合自然图像 |
False Floyd-Steinberg(简化抖动) | 当前像素 + 右1,下1 | 较粗糙、噪点少 | 简化版,速度快,占用低,但细节损失明显 |
Stucki | 当前像素 + 周围 12 个像素 | 最细腻、噪点最多 | 扩散范围广,保留渐变最好,但图像看起来"颗粒感重" |
Atkinson | 当前像素 + 周围 6 个像素 | 对比度高,细节适中 | Apple 经典算法,适合图标、UI 元素,强调边缘清晰度 |
扩散范围越小的抖动算法(如简化抖动),所带来的GIF文件体积越小,有点像是图像插帧,插得越少,LZW 所能起的作用越大。
虽然不同抖动处理的算法会影响文件大小,但这个大小很难直接计算估计出来,因此软件中,选择不同的算法,并不会直接造成预估大小的改变,实际是有影响的。
5. 调色板模式
GIF 采用的是索引颜色模式,而不是直接存储每个像素的 RGB 值。
在这种模式下:文件中保存一张颜色查找表(Color Table),也叫调色板,每个像素只存储调色板索引值(0~255),显示时再通过查找表把索引转换为实际颜色。
调色板有两种模式可选:局部调色板和全局调色板。

全局调色板是指整个 GIF 文件共用一个调色板,文件体积会较小。
局部调色板是指每一帧可以有自己的局部调色盘,因此不同帧之间的颜色可以完全不同,色彩表现会丰富,文件体积会更大。
总结
GIF的格式注定其无法采用更高效的帧间压缩方式,因此,压缩GIF就只能从两个角度考虑:每一帧大小和色彩表现。
参考
1\] CTF Wiki:https://ctf-wiki.org/misc/picture/gif