详解用Python pillow 创建和保存GIF动画

  • Post category:Python

下面是用Python pillow创建和保存GIF动画的完整攻略:

1. 安装Pillow

在使用Pillow之前需要先安装它,可以使用pip直接安装,命令如下:

pip install Pillow

2. 创建GIF动画

Pillow中提供了一个ImageSequence模块,可以很方便地处理GIF动画。

首先,需要创建一组带有透明度的图像,然后将这些图像逐一加入一个ImageSequence对象中。

下面是一个创建并保存GIF动画的示例代码(假设图片文件名为test*.png):

from PIL import Image, ImageSequence

# 创建一个ImageSequence对象
images = []

# 加入所有带有透明度的PNG图像
for i in range(10):
    filename = 'test{}.png'.format(i)
    with Image.open(filename) as im:
        images.append(im)

# 创建并保存GIF动画
images[0].save('output.gif', save_all=True, append_images=images[1:], optimize=False, duration=100, loop=0)

上面的代码中,我们首先创建了一个ImageSequence对象images,然后循环遍历所有带有透明度的PNG图像,将每个图像加入到ImageSequence对象中。

接着,我们调用了Image对象的save方法来保存GIF动画,其中:

  • 第一个参数是要保存的文件名;
  • save_all参数表示保存所有帧的图片,也就是GIF动画;
  • append_images参数表示需要添加到GIF动画中的图像列表;
  • optimize参数表示是否需要优化GIF动画,这里设置为False表示不进行优化;
  • duration参数表示每个图像的显示时长,单位是毫秒(ms);
  • loop参数表示GIF动画的循环次数,0表示无限循环。

3. 示例说明

下面,我们来看两个具体的示例说明。

示例1

假设我们需要创建一个简单的闪烁的文字效果的GIF动画,代码如下:

from PIL import Image, ImageDraw, ImageFont, ImageSequence

# 文字、字体、字号、颜色等参数
text = 'Hello, World!'
font_file = 'arial.ttf'
font_size = 36
color = (255, 155, 0)

# 创建一个ImageSequence对象
images = []

# 循环生成所有GIF图像
for i in range(10):
    with Image.new('RGBA', (200, 50), color=(0, 0, 0, 0)) as im:
        draw = ImageDraw.Draw(im)
        font = ImageFont.truetype(font_file, font_size)
        draw.text((20, 5), text, font=font, fill=color)
        images.append(im)

# 创建并保存GIF动画
images[0].save('output.gif', save_all=True, append_images=images[1:], optimize=False, duration=100, loop=0)

上面的代码中,我们首先定义了文字、字体、字号、颜色等参数,然后循环遍历10次,每次生成一张透明的黑底PNG图片,并在上面绘制带有指定颜色的文字。

接着,我们将所有PNG图片加入到ImageSequence对象images中,并最终保存为一个GIF动画文件。

示例2

假设我们有一组图片,需要将它们拼接成一个GIF动画,代码如下:

from PIL import Image, ImageSequence

# 加载所有图片
images = []
for i in range(10):
    filename = 'test{}.jpg'.format(i+1)
    with Image.open(filename) as im:
        images.append(im)

# 计算拼接后的图片大小
total_width = sum([im.size[0] for im in images])
max_height = max([im.size[1] for im in images])

# 创建新的空白图片
with Image.new('RGB', (total_width, max_height)) as im:
    x_offset = 0
    for sub_im in images:
        im.paste(sub_im, (x_offset, 0))
        x_offset += sub_im.size[0]

    # 创建并保存GIF动画
    frames = [frame.copy() for frame in ImageSequence.Iterator(im)]
    frames.reverse()  # 需要反转图片顺序
    im.save('output.gif', save_all=True, append_images=frames, optimize=False, duration=100, loop=0)

上面的代码中,我们首先加载所有图片,并计算拼接后的图片大小。

然后,我们创建一个新的空白图片,并循环遍历所有图片,将它们依次拼接到空白图片的右侧。

最后,我们将空白图片按顺序保存为GIF动画,并将保存过程中需要使用的所有帧图像保存到一个列表中。

注意,因为拼接后的GIF动画是从左到右依次播放的,所以保存时需要将帧图像反转以保证播放顺序正确。