百科狗-知识改变命运!
--

如何使用Python对GIF进行压缩

是丫丫呀1年前 (2023-11-21)阅读数 12#技术干货
文章标签文件夹

一、背景

前天在给微信公众号上传文章的时候,文章里面有一个图片是gif的,在上传的过程中报错了,说是图片超大了。搜索之后发现图片需要小于5m。

那么问题就转化为怎么把当前的gif给缩减到5m以内本着有轮子用轮子,没有轮子造轮子的精神,网上搜索一番。

发现一些现象

1、压缩要不就是需要会员才能下载;

2、要不免费的只能压缩5m以下的。

考虑到能动手不花钱的本性,我觉得要自己搞一下。

知识背景:

众所周知,gif图就是由若干组图片组成的一种文件格式,有多张有一定差异的图片连续播放,间隔时间较小,欺骗了我们的眼睛和大脑,然后我们以为是一个完全连续的。其实就是一个类似快速翻书的操作。

二、方案选型

方案一

因为gif是有多种图片做的,那我们就考虑把图片减少一些,比如说原来是100张是10m,我给缩减到10张,那体积可不就要缩小到1m左右了吗?当然,为了用户看起来不是那么卡顿,我就拍脑袋给缩减到20张吧,即只有原来的1/5。

方案二

如果缩减的图片太多导致gif看起来卡顿的话,我们可以考虑不缩减图片的张数,但是我们可以压缩图片。

方案三

最后的都是重要的,如果前面两个都无法满足的话,那就可以考虑把他们进行叠加。先减张数,再压缩拆分的图片。

三、项目落实

整体流程如下:

if__name__=="__main__":   #设置源gif的地址   sourceGifPath="/Users/user/test/f79a3e2c2e864863a6b1a66791cb0950_tplv-k3u1fbpfcp-watermark.gif"   #将gif拆分成多个图片,并保存在本地   SplitGif(sourceGifPath)   #将指定位置的文件下的图片按照文件名索引排序,做成gif   Combine2Gif(sourceGifPath[:-4],sourceGifPath[:-4]+"_result.gif")   print("==finished==") 

1、将源gif读入内存

如何使用Python对GIF进行压缩

2、将gif拆分成png,并保存

defSplitGif(gifPath):   #获取png存储的文件夹的地址   pngDir=gifPath[:-4]   #要存储的文件夹下清理干净,避免影响当前操作   rmPngDir(pngDir)   #创建存储的文件夹   os.mkdir(pngDir)   #把指定gif拆分后存储到指定文件夹   savePngToDir(gifPath,pngDir) 

2.1、获取要存储的地址

2.2、清空并移除存储png的文件夹

defrmPngDir(pngDir):   ifos.path.exists(pngDir):     files=os.listdir(pngDir)     #如果不一个一个的移除文件夹下的文件的话,无法移除文件夹     forfileinfiles:       file=pngDir+"/"+file       os.remove(file)     os.rmdir(pngDir) 

2.3、创建存储png的文件夹

2.4、将gif拆分成png,并保存

defsavePngToDir(gifPath,pngDir):   #通过路径传教image对象   image=Image.open(gifPath)   try:     #循环,通过异常方案退出循环     whileTrue:       #获取当前的索引的位置       current=image.tell()       #创建文件路径       pngPath=pngDir+'/'+str(current)+'.png'       image.save(pngPath,quality=100)       #索引后移,越界后异常,退出当前循环       image.seek(current+1)   exceptEOFErrorase:     print(e)     pass 

3、按照一定的间隔读取2中的png,并生成gif

defCombine2Gif(folderPath,gifFilePath):   GenerateGif(0.1,gifFilePath,getPngArray(folderPath)) 

3.1、获取所有的png

defgetPngArray(folderPath):   files=os.listdir(folderPath)   pngFiles=[]   #通过设置step,将文件的大小修改为原来的体积的1/step   foriinrange(0,len(files),5):     pngFiles.append(folderPath+"/"+('%d.png'%i))   returnpngFiles 

3.2、将png合并成gif

defGenerateGif(step,gifPath,filterPngs):   images=[]   forfilePathinfilterPngs:     images.append(imageio.imread(filePath))   #生成gif,duration是播放两个图片之间的间隔时间   imageio.mimsave(gifPath,images,duration=step) 

四、全部的代码

#!/usr/local/bin/python3 #-*-coding:utf-8-*- fromPILimportImage importos importimageio   defSplitGif(gifPath):   #获取png存储的文件夹的地址   pngDir=gifPath[:-4]   #要存储的文件夹下清理干净,避免影响当前操作   rmPngDir(pngDir)   #创建存储的文件夹   os.mkdir(pngDir)   #把指定gif拆分后存储到指定文件夹   savePngToDir(gifPath,pngDir)   defrmPngDir(pngDir):   ifos.path.exists(pngDir):     files=os.listdir(pngDir)     #如果不一个一个的移除文件夹下的文件的话,无法移除文件夹     forfileinfiles:       file=pngDir+"/"+file       os.remove(file)     os.rmdir(pngDir)   defsavePngToDir(gifPath,pngDir):   #通过路径传教image对象   image=Image.open(gifPath)   try:     #循环,通过异常方案退出循环     whileTrue:       #获取当前的索引的位置       current=image.tell()       #创建文件路径       pngPath=pngDir+'/'+str(current)+'.png'       image.save(pngPath,quality=100)       #索引后移,越界后异常,退出当前循环       image.seek(current+1)   exceptEOFErrorase:     print(e)     pass   defCombine2Gif(folderPath,gifFilePath):   GenerateGif(0.1,gifFilePath,getPngArray(folderPath))   #获取文件的数组 defgetPngArray(folderPath):   files=os.listdir(folderPath)   pngFiles=[]   #通过设置step,将文件的大小修改为原来的体积的1/step   foriinrange(0,len(files),5):     pngFiles.append(folderPath+"/"+('%d.png'%i))   returnpngFiles   defGenerateGif(step,gifPath,filterPngs):   images=[]   forfilePathinfilterPngs:     images.append(imageio.imread(filePath))   #生成gif,duration是播放两个图片之间的间隔时间   imageio.mimsave(gifPath,images,duration=step)   if__name__=="__main__":   #设置源gif的地址   sourceGifPath="/Users/user/test/f79a3e2c2e864863a6b1a66791cb0950_tplv-k3u1fbpfcp-watermark.gif"   #将gif拆分成多个图片,并保存在本地   SplitGif(sourceGifPath)   #将指定位置的文件下的图片按照文件名索引排序,做成gif   Combine2Gif(sourceGifPath[:-4],sourceGifPath[:-4]+"_result.gif")   print("==finished==") 

五、结尾

作为一个追求高效的程序员,我就做一个能满足我需求的方案,即方案一。至于方案二和方案三,有兴趣的朋友可以举一反三。

以上内容为大家介绍了如何使用Python对GIF进行压缩,希望对大家有所帮助,如果想要了解更多Python相关知识,请关注IT培训机构:开发教育。http://www.baikegou.com/


鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)