一、问题的引出

不过在大部分情况下,你面对的是不同分辨率的图片,有竖版照片、横版照片、高宽相同的照片,即使是竖版或横版,其高宽比也不相同。那么,如何将不同分辨率的照片制作为GIF动画呢?

由于GIF动画要求所有帧的分辨率必须相同,因此要先把不同分辨率的图片调整为相同的分辨率。一种简单粗暴的方法是直接将所有源图片resize到相同大小。

下面介绍将不同大小照片制作为GIF的方法和过程。这个过程和上一篇文章所介绍的过程类似,只不过增加了使用图像处理模块scikit image的resize()方法来改变图片分辨率的步骤。

二、使用的编程语言和库

关于编程工具,推荐使用Anaconda Python. 它集成了许多常用的库,当然包括图像处理模块scikit-image、制作GIF用的imageio模块。用户不必另行安装,非常方便初学者使用。如果你还没使用过Anaconda Python,请到本号的免费专栏Anaconda Python的安装和使用,了解它的下载、安装、使用方法。

三、准备工作

首先准备2张以上的照片。照片的大小可以不同。为验证本文介绍的方法和代码,建议准备至少一张竖版、一张横版照片。所有的照片要为相同的格式。这里我们使用jpg格式。将照片放到一个文件夹里,按照你希望的播放顺序将各张照片按升序命名。另外再建立一个文件夹,用来保存制作好的GIF文件。当然也可以在程序中动态创建文件夹,以后再撰文说明如何来创建。做好这些准备,就可以编写程序,逐个读取照片制作GIF。

四、GIF制作思路

首先导入os模块,用于获取指定文件夹下所有文件的名字;从scikit-image模块(skimage)的transform子模块导入resize()方法,用于改变图片的分辨率;导入imageio模块,用于读取图片和制作GIF。

其实关于读取图片和改变其分辨率,还有更好的库可以用,例如OpenCV. 但是OpenCV需要用户自己安装。等以后大家对Python比较熟悉了,再介绍使用OpenCV的方法。它不但能处理照片,还可以处理视频。比如从视频提取帧,将照片制作为视频,等等。

然后,使用os.listdir()方法来获取指定路径下所有图片的名字列表。

第三步,创建一个初始化为空的列表,用于保存读取的每张图片。

第四步,创建一个循环体,遍历图片名字列表,拼出每张照片的全路径名称,使用imageio.imread()方法读取每张照片,使用resize()方法将每张图片改变为你希望的分辨率。为便于从手机观看,建议将图片的高:宽比例设置为16:9. 然后使用append()方法将resize后的图片添加到图片列表,直至所有图片处理并添加到图片列表完毕。

第五步,使用mimsave()方法将图片列表保存为GIF。mimsave()方法主要有4个参数,第1个参数是要保存的GIF文件全路径名称,包括后缀名.gif;第2个参数是图片列表;第3个参数是保存类型,设置为字符串'GIF';第4个参数为每张图片播放持续时间,单位为秒。

五、示例源代码

将不同大小jpg格式的照片制作为GIF动画的示例源代码如下。

import os,imageiofrom skimage.transform import resizepath_source='.../images/'     #源照片位置path_dest='.../gif/'           #GIF要保存的位置source_file_list = os.listdir(path_source)  #读取文件夹下所有文件名称frames = []  #保存帧的列表for file in source_file_list:    full_name=path_source+file #照片的全路径名称    frame=imageio.imread(full_name) #读取照片    frame=resize(frame, (800,450,4)) #高宽比16:9    frames.append(frame) #将照片添加到列表       #duration:单帧持续时间,单位simageio.mimsave(path_dest+'mygif2.gif', frames, 'GIF', duration=0.8)

这个程序代码比上一篇文章制作GIF动画的代码也就多了导入resize方法和使用resize()改变图片分辨率这两行语句,总共12行。制作的GIF效果如下图所示。





可以看出,照片的比例失真了。这是由于对原始照片,只是简单的使用resize()方法将其改为为指定的分辨率,改变后的分辨率与原照片不一致,因此看起来高宽比例失真。