当前位置:   article > 正文

python 2.7实现gif图片缩小_pillow库处理gif变成静态图片

pillow库处理gif变成静态图片

注:本文基于CentOS 7.2系统操作,使用的python版本为:2.7.5

1、背景

最近在发gif表情的时候发现有些动图太大了,一发就占了一整屏,不太舒服,想着有啥办法能缩小gif的大小,于是乎想起了python。

大概了解了一下,需要使用到PIL的Image和ImageSequence模块,但是这里有一个天坑,让我折腾了一天的时间。。。

那就是:原生PIL不支持gif的保存,需要使用pillow。

因为这,我缩小后的gif只有一帧,还动不了,我还以为是我代码哪里错了,so sad。

2、安装pillow

pip install pillow
  • 1

对,就只需要这么一个语句。

3、代码

废话不多说,上代码。

#!/usr/bin/env python

from PIL import Image, ImageSequence
import sys, os

if len(sys.argv) < 3:
    print("input invalid!")
    print("you need input ingif and outgif.")
    exit(1)

inf = sys.argv[1]
outf = sys.argv[2]

gif = Image.open(inf)
dura = gif.info['duration']
imgs = [f.copy() for f in ImageSequence.Iterator(gif)]

index = 0
imglist = []
os.mkdir("images")
for frame in imgs:
    frame.save("./images/%d.png" % index)
    im = Image.open("./images/%d.png" % index)
    im.thumbnail((128,128), Image.ANTIALIAS)
    imglist.append(im)
    index += 1

os.system("rm -rf ./images")

imglist[0].save(outf, 'gif', save_all=True, append_images=imglist[1:], loop=0, duration=dura)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

4、重点说明

gif图片压缩的思路大概就是:获取gif的每一帧,将每一帧图片缩小,然后将缩小的图片重新合成gif图片。

1、获取帧信息
使用ImageSequence模块的迭代器去遍历gif动图的每一帧,然后放到imgs列表里。

imgs = [f.copy() for f in ImageSequence.Iterator(gif)]
  • 1

上述语句相当于下面的简写:

for f in ImageSequence.Iterator(gif):
    imgs.append(f.copy())
  • 1
  • 2

2、将帧信息保存为静态图片

frame.save("./images/%d.png" % index)
  • 1

上一个步骤我们已经获取了动图的帧信息,这里使用save方法,将帧信息保存为png图片。

是否能保存为jpg格式呢?答案是不能,如果需要将其保存为jpg格式,需要先将帧信息转成RGB格式,然后才能保存为jpg格式。

frame = frame.convert('RGB')  
frame.save("./images/%d.jpg" % index)  
  • 1
  • 2

这是什么原因呢?据我考证(不一定正确),帧信息的通道和PNG通道一样,有四个通道,与平常的RGB三通道不同,多了一个A通道,用于表示黑白灰通道。因此如果直接转换为jpg格式,多的一个A通道不知道如何处理。

3、压缩图片
其实就是改变图片尺寸大小。

im.thumbnail((128,128), Image.ANTIALIAS)
  • 1

thumbnail方法就是生成指定尺寸的缩略图。其中(128,128)表示缩小后的尺寸,Image.ANTIALIAS表示图片的质量。这个方法和resize类似。

4、重新合成gif
处理完所有图片后,就需要将所有帧信息重新合成。

imglist[0].save(outf, 'gif', save_all=True, append_images=imglist[1:], loop=0, duration=dura)
  • 1

这里使用的还是save方法,不过参数多了几个。通过设定save_all=True参数和 append_images,可以一次性将多帧图像同时存入GIF图片。还有一个duration参数控制的是帧率,我们可以直接从原图片中获取该信息。

dura = gif.info['duration']
  • 1

除了帧率,gif.info返回的信息还有很多其他信息,

{'background': 0, 'extension': ('NETSCAPE2.0', 803), 'version': 'GIF89a', 'transparency': 23, 'duration': 60, 'loop': 0}
  • 1

另外,loop参数也很重要,如果没设置这个参数会出现动图动一会儿就不动的情况。

这样,我们就把大的gif图片缩小了,效果如下。

大图展示:
这里写图片描述

小图展示:
这里写图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/912979
推荐阅读
相关标签
  

闽ICP备14008679号