如何将gif逐帧分解

DinS          Written on 2018/4/3

本文介绍如何利用graphicsmagick将一张gif逐帧分解,希望读者已经将环境搭建好了。

一、Magick++基础使用方法

在进入正题前先看看基本使用。

更多使用的示例可见http://www.graphicsmagick.org/Magick++/index.html#installation中的Magick++ User-Level Classes,点进去即可查看,主要看Image这个类,这个是Magick++最核心的类。
最简单的例子:图像格式转换。比如在工程路径放一个图标:

然后写如下代码:

注释很清晰了,运行看结果:

确实生成了!高级的抽象是好用的原因。

二、分解gif

其实我使用GraphicsMagick的本意是想把一张gif按帧切分成许多图片,使用Magick++可以很轻松地做到这一点。看代码:

非常简洁现代的c++代码,运行结果:

然而这种方法会遇到问题:对于有transparent的gif会失效,比如换个二次元图片试试看。

这个跟gif本身的结构有关,有些gif并非一帧一帧渲染,而是将后一帧重叠到前一帧,这样节省空间。对于这种gif,不能用上述方式,而是要换一种,叫做coalesce。看一下官方文档:

大图点这里

使用coalesceImages是让gif播放一遍,然后把每一帧完全渲染出来,这样得到的就是完整的gif序列。代码如下:

大图点这里

增加了两行代码,注意这种方式运行起来时间会比较长。
结果:

三、分解后的注意事项

但是注意,还没结束。这样得到的png有的时候会与标准png格式不同。
如果安装了GraphicsMagick安装包,可以使用gm identify -verbose path…打印图片详细信息,会发现有时候图片会缺失Opacity通道:

对于看来说不重要,但是如果生成的图片要交由其他程序调用,则可能会出问题。于是要这么解决:

大图点这里

设置opacity,这样会增加通道。副作用是原来透明的部分会被填充成白色。

再次使用命令行,可以看到发生了变化:

这个就是比较正常的了。
实际上如果用Paint.exe打开重新保存,也会自动加上这些还有点别的。

更多使用方法可以去官网查看,遇到问题随时查即可。