答主@王泰 已经说的很详细了。网上制作循环GIF图一般使用PS软件,我这里补充一段将不循环的GIF图转为循环的Python代码,对于程序员们更友好和便捷。
这个问题是有实际场景的:知乎目前的文章只允许插入1MB大小以内的GIF图,而大多数表情包之外的动图都超出了这个大小,这时就需要对GIF的尺寸进行裁剪,或者进行抽帧。在Mac自带的预览功能里可以直接完成这两个操作,但代价就是原本循环播放的GIF变得只动一次了。使用以下代码:
from PIL import ImageSequence, Image import imageio, os location = "/path/to/" # 文件目录 gif_file = os.path.join(location, "origin.gif") # 输入GIF文件名 out_file = os.path.join(location, "output.gif") # 输出GIF文件名 # 这里如果想使用灰度图,可以使用`.convert("L")`代替,参考https://pillow-cn.readthedocs.io/zh_CN/latest/handbook/concepts.html#mode frames = [frame.copy().convert("RGBA") for frame in ImageSequence.Iterator(Image.open(gif_file))] imageio.mimsave(out_file, frames, 'GIF', duration=0.5) # duration表示两帧之间播放的间隔时间,也可不设,使用默认
再添加一些逻辑,可以将不循环的GIF图批量转为循环的。在GIF的保存时,不要使用网上流行的这种(可能会影响循环):
frames[0].save("out.gif", save_all=True, append_images=frames[1:])
另外,也可以针对知乎的这个1MB场景,配合以上代码,写一个自动的GIF压缩程序~
我们现在说的GIF图片全称是Graphics Interchange Format,是一种256色的图片压缩(LZW协议)文档,主要用来存储动态图片。GIF图片有两种格式分布是1987年的GIF87a和1989年GIF89a版本。
其中GIF89a扩展了图形控制区块、备注、说明、应用程序接口等四个区块,并提供了对透明色和多帧动画的支持[1]。这也是我们现在最广为使用的协议。
GIF89a 设定部分属性如下图所示[2]:
1995年Netscape 为了让GIF可以更好的支持动画和视频剪辑,GIF89a又增加了图像控制扩展功能(Graphics Control Extension (GCE)),每个frame的图片都可以添加GCE部分,用来描述frame之间的延迟时间和循环次数。[3]
上图中 31D行,定义的就是重复播放次数。
所以,如果你的GIF动画不循环播放,一种可能是GCE设置成了1就是只播放一次;第二种可能是你的GIF动画中没有GCE部分。要是GIF动画没有GCE,那就要看播放GIF动画的工具是怎么处理默认逻辑了,有可能只播放一次,也有可能循环播放。