gif

Posted on By ᵇᵒ

前言

窃了一个 gif 图片,用在自己博客上,发现播放一次之后便不再循环了,体验很不好。
比较好的一种方式是像知乎那样只展示首帧静态图,主动点击 gif 后播放,博客是基于 jekyll,搜到了类似 GifTag 的 jekyll 插件。
次一点的方式就是 gif 丢在那里让它一直循环播放。

GIF 文件格式

GIF:图像交换格式(Graphics Interchange Format),是由美国 CompuServe 公司在1987年所提出的图像文件格式。 包括文件头(Head Block)、注释块(Comment Block)、循环块(Loop Block)、控制块(Control Block)、GIF图像块(Image Block)、文本块(Plain Text Block)、附加块(Application Block)

版本

GIF 具有 GIF87a 和 GIF89a两 个版本。

  • GIF87a 版本是 1987 年推出的,一个文件存储一个图像,严格不支持透明像素;GIF87a 采用 Lempel-Zev-Welch(LZW)压缩算法,它能够在保持图像质量的前提下将图像尺寸压缩百分之二十到二十五。
  • GIF89a 版本是 1989 年推出的很有特色的版本,该版本允许一个文件存储多个图像,可实现动画功能,允许某些像素透明。在这个版本中,为 GIF 文档扩充了图形控制区块、备注、说明、应用程序编程接口4个区块,并提供了对透明色和多帧动画的支持。

usage

如上所知, gif 文件里含有 loop block,改变 loop block 的数据可以控制循环播放次数。
显然,我们无法直接修改 loop block,需要借助相关工具。常用的工具有 GifsicleImageMagick 等。 推荐 ImageMagick,开源非盈利,macOS 上可以使用 Homebrew 安装。

# -loop 指定 gif 的循环次数,为 0 时代表无限循环
convert -loop 0 input.gif output.gif
# -delay 指定 gif 的每一帧的显示时间,单位为 10ms
convert -delay 100 input.gif output.gif
# 将 gif 转成 png sequence,最终输出 img 文件夹下会是 output-0.png output-1.png ···
# png 合成 gif 的时候可能会优化,后面的帧内容只包含首诊或者前一帧的变化,-coalesce 使得每一帧都是完整的内容 而不只是变化的地方 
convert -coalesce input.gif img/output.png
# 将 png sequence 合成 gif(默认无限循环),前面每帧显示 1 秒,最后一帧显示 3 秒,其中 N 即最后一张 png 的序列
# 假设 png sequence 为 img 文件夹下命名规律 input-0.png input-1.png ···
convert -delay 100 img/input-{0..N-1}.png -delay 300 img/input-N.png output.gif