仅使用Pillow库是否可以生成GIF动画?

3

我希望能够将numpy数组转换为图像。首先,我已经学会了如何将3D (高度 x 宽度 x 颜色) 数组转换为图像。经过一些研究,我发现PIL(或Pillow)是最自然的方法。目前我是这样做的(它可以正常工作):

from PIL import Image
import numpy as np

if __name__ == '__main__':
    h = 4
    w = 8
    arr = np.zeros((h,w,3), dtype=np.uint8)

    arr[0, 0, :] = [255,255,0]
    arr[3, 7, :] = [0,255,0]

    img = Image.fromarray(arr, 'RGB')
    img.save('viz.png')

作为下一步,我希望能够获取一个3D数组列表(或者是4D数组,其中时间是额外的维度),并生成相应的动画。到目前为止,我还没有找到如何实现它的方法。
看起来Pillow可以读取gif动画。使用ImageSequence我们可以访问它的帧。然而,我无法找到如何将一系列图像放入动画中的方法。
我看到一些解决方案使用“images2gif”,但我想留在单一库中。
添加: 这里的答案没有回答我的问题。他们使用了我甚至无法通过pip安装的“gifmaker”库。

1
@Reti43,不,我想在Pillow中完成它,那里的答案使用了gifmaker - Roman
这是Pillow的一个脚本,它是一个包装函数,用于调用Image.save()并带有特殊参数。这对你不起作用吗? - Reti43
在我尝试使用Image.save()函数并设置save_all=True选项之前,我首先需要弄清楚如何创建一个由多个帧组成的图像对象。将3D数组替换为3D数组列表是行不通的。 - Roman
@Reti43,我也尝试使用4D数组代替3D数组列表。Pillow报错说维度太多了。 - Roman
1
好的,我现在明白了。很抱歉错过了那个细节。经过搜索,我找不到任何证据表明Pillow支持您所要求的内容,因此您可能需要创建一个修改后的GifImagePlugin,或者从images2gif中复制代码,将其保存为动画gif并重新加载到Image对象中。我知道,这两种方法都不是理想的选择。 - Reti43
1个回答

4
因此,问题的主要目的是生成一系列3D数组(帧)或4D矩阵(具有宽度、高度、颜色和时间作为维度),而不使用对Python“外部”的工具。看起来PIL库无法做到这一点。至少没有简单的方法,需要使用技巧或解决方法。但是,可以通过使用"moviepy"库来实现目标。以下是该库提供的优雅解决方案:
import numpy as np
import moviepy.editor as mpy

def make_frame(t):

    h = 100
    w = 100

    ar = np.zeros((h, w, 3))

    for hi in range(h):
        for wi in range(w):
            for ci in range(3):
                ar[hi, wi, ci] = 255.0*t/15.0
    return ar


if __name__ == '__main__':

    clip = mpy.VideoClip(make_frame, duration=15.0)
    clip.write_gif('ani.gif', fps=15)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接