导读:本文介绍如何使用Python将不同大小的照片制作为GIF动画,文末附源代码。阅读完本文,你将学会使用Python编写程序,将不同大小的照片制作为心仪的GIF动画。
在上一篇文章里,介绍了使用Python和imageio,不改变图片大小,把相同大小(分辨率)的多张照片制作为GIF的方法。一般来说,只有从视频提取的帧序列的分辨率才保持一致。此时使用该方法是没有问题的。
一、问题的引出
不过在大部分情况下,你面对的是不同分辨率的图片,有竖版照片、横版照片、高宽相同的照片,即使是竖版或横版,其高宽比也不相同。那么,如何将不同分辨率的照片制作为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()方法将其改为为指定的分辨率,改变后的分辨率与原照片不一致,因此看起来高宽比例失真。
照片比例失真将影响观赏效果,那么该如何做到既能够将不同大小的照片改变为具有相同分辨率,又能够保证原照片的比例不失真呢?这个解决方法将在下一篇文章中进行介绍。请继续关注本号的后续文章。欢迎转发评论,有任何问题请在评论区留言。