大家好,我是小一有趣,教你用Python秒变斗图大师!_python

使用 Python 操作 Word、PDF和图片并进行一些简单合并、分割等大家都会,甚至连加水印、解析表格等高级的操作大家都会了,那么:操作 GIF 图片呢?

知道你不会,今天就教教你用 Python 实现对 GIF 动图的拆分、合成、和倒放,极其容易上手,斗图再也不怕没资源


  准备

导入相关库:

import os
import imageio
from PIL import Image, ImageSequence

​os​​​库是用来操作文件夹的,​​imageio​​​库是用来合成 GIF,​​PIL​​​库大家应该都很熟悉,这次用到它的​​Image​​​和 ​​ImageSequence​​模块,用来实现GIF的读取和拆分。

所有库可以直接用pip命令进行安装:

pip install 库名

准备一张 GIF 动图,本文只要此动图的基础之上进行操作:

有趣,教你用Python秒变斗图大师!_python_02

合成或者倒放GIF动图也可以使用其它若干张图片进行操作。


  拆分

拆分相比合并和倒放容易很多,这里介绍两种方法。先用​​os​​​在目录下创建一个名为​​拆分​​的文件夹:

if not os.path.exists('拆分'):
os.makedirs('拆分')

第一种方法是使用​​Image​​​模块下的​​seek​​函数,可以直接拆分;拆分后建议按顺序命名图片:

img = Image.open('噢特曼.gif') # 打开GIF动图
try:
i = 1
while True:
img.seek(i) # 拆分
img.save(f'拆分/{i}.png') # 保存
i += 1
except:
pass

第二种方法相比第一种简洁很多,用的是​​ImageSequence​​​模块中的​​Iterator​​函数:

img = Image.open('噢特曼.gif')
i = 0
for f in ImageSequence.Iterator(img): # 循环遍历GIF中的帧
i += 1
f.save(f'拆分/{i}.png') # 保存

从​​Iterator​​​函数的源码可以看出,它其实是在​​seek​​​函数基础之上进行封装的:有趣,教你用Python秒变斗图大师!_python实现_03

两个方法得出的结果都一样,动图的每一帧都保存下来了:有趣,教你用Python秒变斗图大师!_python_04


  合并

​imageio​​​是个第三方库,它可以直接读取很多格式的图片和视频,然后可以将图片和视频转换成其它格式。本文用到的是​​imageio​​​库的​​imread​​​和​​mimsave​​函数,一个读取,一个保存:

img_list = []
imagelist = os.listdir('拆分') # 打开文件夹
imagelist.sort(key=lambda x: int(x.split('.')[0])) # 按照图片中的数字进行升序排序
for i in range(len(imagelist)): # 计算图片总数进行遍历
img_list.append(imageio.imread('拆分/' + imagelist[i])) # 读取图片
imageio.mimsave('合并噢特曼.gif', img_list, 'GIF', duration=0.05) # 保存 duration 每一帧的速度

还可以把一些自己心仪的图片配上文字合成动图:有趣,教你用Python秒变斗图大师!_倒序_05


  倒放

倒放其实是把动图拆分后,利用方法对拆分的帧进行倒序排序,再进行合成保存,这里介绍两种方法。

第一种只要依然是使用​​imageio​​​ 进行合成 GIF 动图,但更改了排序方式,把它改为降序排序,在代码中添加​​reverse=True​​ :

img_list = []
imagelist = os.listdir('拆分')
imagelist.sort(key=lambda x: int(x.split('.')[0]), reverse=True) # reverse=True时,排序方法改为降序排序
for i in range(len(imagelist)):
img_list.append(imageio.imread('拆分/' + imagelist[i]))
imageio.mimsave('倒放.gif', img_list, 'GIF', duration=0.05)

效果预览:

有趣,教你用Python秒变斗图大师!_python实现_06

第二种用到 Python 内置函数​​reverse()​​进行帧的倒序排序,但效果不是很好,动图放着放着就会卡住,而且不能设置动图的每一帧的速度。

im = Image.open('噢特曼.gif')  
sequence = []
for f in ImageSequence.Iterator(im):
sequence.append(f.copy())
sequence.reverse() # 将列表中的帧通过reverse()函数进行倒序
sequence[0].save('倒放噢特曼.gif', save_all=True, append_images=sequence[1:]) # 保存

效果预览:

有趣,教你用Python秒变斗图大师!_python实现_07

以上便是今天的全部内容了,欢迎一键三连!