上一篇文章里使用MyQR制作了一个动态二维码,然而CSDN和微信只允许上传5M以下的图片,所以我着手寻找压缩动图的方法,一开始想使用Opencv模块处理图像,但是发现该模块无法压缩动图,故而寻找别的解决办法,废话不多说,下面展示源码
注:这里我使用的是python3,编辑器是pycharm
import os
import imageio
from PIL import ImageSequence, Image
# 提取gif逐帧保存并返回帧数
def getIndex(img):
index = 1
# 图片为gif时获取帧数index并逐帧压缩
if img.is_animated == True :
try:
for frame in ImageSequence.Iterator(img):
frame = frame.convert('RGB') # 逐帧转换成RGB
frame.save("index%d.jpg" % index) # 保存每一帧
pressImg('index%d.jpg'% index) # 调用压缩图片函数逐帧压缩
index = index + 1
return index
except Exception as e:
print('Error:' + e)
# 非gif时帧数index为1
else:
return index
# 压缩图片
def pressImg(ImgName):
img = Image.open(ImgName)
img.convert('RGB')
if max(img.size[0], img.size[1]) > 128: # 若帧图宽高有一项大于128则压缩
img.thumbnail((128, 128))
img.save('press-'+ImgName, quality=60) # 此处quality为保存图片质量 取值范围由1(最差)-95(最好)
return 'OK'
# 合并gif
def mergeGif(indexnum):
images = []
for i in range(1, indexnum):
images.append(imageio.imread('press-index%d.jpg' % i))
imageio.mimsave(r'C:\Users\Evaron\Desktop\QRTEST.gif', images)
# 删除中间产生的图片
def removeImg(indexnum):
for i in range(1,indexnum):
af = 'press-index' + str(i) + '.jpg'
bf = 'index' + str(i) + '.jpg'
if os.path.exists(af):
os.remove(af)
if os.path.exists(bf):
os.remove(bf)
gif = Image.open(r'C:\Users\Evaron\Desktop\QRTEST.gif') #读取文件
indexnum = getIndex(gif) #提取每一帧,保存为jpg格式,返回总帧数,此过程会生成许多jpg文件
mergeGif(indexnum) # 压缩jpg,合并jpg成gif
removeImg(indexnum) # 删除中间jpg文件
如图为压缩前的图片大小:
这里对图片运行该代码段,得到压缩后的图片大小为:
这里再展示下效果图,可以看到效果还是很明显的: