· 1 min read

动画GIFs如何实际工作——从Canvas框架到LZW压缩

GIF格式已有39年历史,仍然随处可见. 下面是点击“ Export” 和获得文件之间发生的情况—— 帧捕获、 颜色量化、 LZW 压缩, 以及为什么您的 GIF 是 4MB .

为何全球投资框架仍然存在

Graphics Interchange格式由CompuServe创建于1987年[CompuServe, 1987]. 它支持动画,透明,以及无损的压缩. 每帧限256种颜色. 它没有音频。 它会产生大的文件。 根据每一项技术措施,它本应在几十年前被取代.

然而:Discord,Slack,iMessage,Twitter,Reddit,以及电子邮件都支持GIFs本土化. GIPHY每天服务超过100亿GIF[GIPHY,2020]. 该格式之所以持续,是因为它到处工作,不需要解码器,并且自动播放. 没有其他格式有通用支持和零软体回放的这种组合.

理解GIFs如何在三维之外发挥作用是有用的——它解释了为什么您输出的GIF是4MB,为什么梯度看起来是带宽的,以及您可以做些什么.

步骤1:框架捕获

动画GIF是显示的图像(帧)的顺序,顺序为每个图像之间的延迟. 要从画布动画中创建一个,需要定期捕捉画布状态.

在浏览器中,这意味着在每个帧时间读取一个HTML QQ0Q元素的像素数据——一般通过QQ1Q或QQ2Q. 动画提前到目标时间,画布被渲染,像素被捕获. 密钥约束:在读取像素之前,您必须等待浏览器的油漆循环(QQ3Q),否则您要抓取一个 stale 缓冲器.

一个典型的GIF在15个FPS上3秒需要45帧捕捉. 在1080×1080分辨率下,每个帧大约为470万像素.

第2步:颜色量化

GIF支持每个帧最多256种颜色,存储在彩色表(palette)中. 一个典型的画布框有上千种不同的颜色. 降低到256而不明显降解是GIF编码中最难的部分.

标准方法是中间切算法[Heckbert,1982年]:将所有像素按其最红的通道排序,按中位数划分列表,重复为绿色和蓝色,递归性地将色彩空间划分为256个区域. 每个区域的平均值成为调色板条目. 这就是gif.js——图书馆PinePaper使用的工具——Web Workers中的并行主义[Rubaxa, gif.js].

彩色量化是GIFs处理平面-彩色图形好但与照片和梯度斗争的原因. 跨越1080像素的梯度可能使用500+不同的颜色. 压缩到256会产生可见的带宽——离散的阶梯,梯度应该平滑.

你能做些什么 在设计中使用更少的颜色 。 平面形状,坚固填充,文字量化为精细. 平滑的梯度和照相纹理不会 如果你的GIF有带宽,简化调色板,而不是分辨率.

第3步: LZW 压缩

每个帧的像素指数(参照256-color调色板)使用Lempel-Ziv-Welch(LZW)压缩[Welch,1984]进行压缩. LZW在扫描数据时构建了重复字节序列的词典. 当它遇到它之前看到的序列时,它会输出字典索引而不是原始字节.

这意味着GIF压缩在存在大量重复色域——固态背景,平面形状,文本在统一的表面时最为有效. 由于LZW字典很少发现重复序列,具有像素水平变化的复杂纹理会产生差的压缩比.

实际含义: 一个黑色背景的白文本的1080×1080 GIF可能压缩为200KB. 复杂照片的同一分辨率GIF可能是8MB。 文件大小更依赖于视觉复杂性,而不是分辨率或帧数.

步骤4:框架处置和优化

GIF 帧可以指定一个 处理方法: 是在绘制下一个帧之前清除画布, 使上一个帧可见, 还是恢复到 ưμ㼯A 智能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) (中文(简体) ) 最佳质量,最小文件,网络 在iMessage的Safari得到的支持有限
MP4 (H.264) 社交媒体,视频播放器 需要解码器,没有透明度
巴基斯坦 透明全彩动画 在旧浏览器中支持有限

GIF是当您需要通用兼容性和自动播放时的正确选择. 对于质量或文件大小,WebM或MP4更好.

试试看

打开PinePaper Studio,创建设计,导出为GIF. 查看文件大小如何变化 :

  • 增加帧数( 更多帧 = 较大文件, 按比例)
  • 添加梯度( 差的量化 = 较大文件)
  • 使用固态颜色( 好量化 = 较小的文件)
  • 增加画布大小( 每帧更多像素 = 大文件)

每个变化都是对压缩管道的测量. 你不只是制作一个GIF——你正在观察信息理论如何适用于你的设计.

参考资料

  • CompuServe(1987年). 图形交换格式规格,第87a版.
  • GIPHY (2020) (英语). GIPHY年度报告: 10亿日报服务.
  • Heckbert, P. (1982) (英语). 用于框架缓冲显示的色彩图像量化 。 * 计算机图形 (SIGGRAPH)*, 16(3), 297-307.
  • Rubaxa. gif.js – JavaScript GIF 使用Web Workers编码器. github.com/jnordberg/gif.js. 互联网档案馆的存檔,存档日期2013-12-22.
  • Welch, T.A. (1984) (英语). A Technique for High-Performance Data Compression. IEEE 计算机, 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