我有一系列的图片,我想从中创建一个视频。理想情况下,我可以为每帧指定帧持续时间,但固定的帧速率也可以。我在wxPython中这样做,所以我可以渲染到wxDC或我可以将图像保存到文件,如PNG。是否有一个Python库,将允许我创建一个视频(AVI, MPG等)或一个动画GIF从这些帧?

编辑:我已经尝试过PIL,它似乎不起作用。有人能用这个结论来纠正我吗?这个链接似乎支持我关于PIL的结论:http://www.somethinkodd.com/oddthinking/2005/12/06/python-imaging-library-pil-and-animated-gifs/


当前回答

我建议不要使用visvis的images2gif,因为它有PIL/Pillow的问题,并且没有积极维护(我应该知道,因为我是作者)。

相反,请使用imageio,它是为解决这个问题而开发的,并打算保留。

快速而肮脏的解决方案:

import imageio
images = []
for filename in filenames:
    images.append(imageio.imread(filename))
imageio.mimsave('/path/to/movie.gif', images)

对于较长的电影,使用流媒体方法:

import imageio
with imageio.get_writer('/path/to/movie.gif', mode='I') as writer:
    for filename in filenames:
        image = imageio.imread(filename)
        writer.append_data(image)

其他回答

我看到这篇文章,没有一个解决方案是有效的,所以这里是我的解决方案是有效的

到目前为止,其他解决方案存在的问题: 1)对于如何修改持续时间没有明确的解决方案 2)对于乱序目录迭代没有解决方案,而乱序目录迭代对于动图是必不可少的 3)没有说明如何为python3安装imageio

像这样安装imageio: python3 -m PIP Install imageio

注意:你要确保你的帧在文件名中有某种索引,这样它们就可以排序,否则你就无法知道GIF从哪里开始或结束

import imageio
import os

path = '/Users/myusername/Desktop/Pics/' # on Mac: right click on a folder, hold down option, and click "copy as pathname"

image_folder = os.fsencode(path)

filenames = []

for file in os.listdir(image_folder):
    filename = os.fsdecode(file)
    if filename.endswith( ('.jpeg', '.png', '.gif') ):
        filenames.append(filename)

filenames.sort() # this iteration technique has no built in order, so sort the frames

images = list(map(lambda filename: imageio.imread(filename), filenames))

imageio.mimsave(os.path.join('movie.gif'), images, duration = 0.04) # modify duration as needed

我使用images2gif.py,这很容易使用。它似乎是文件大小的两倍。

26个110kb的PNG文件,我期望26*110kb = 2860kb,但my_gif.GIF是5.7mb

另外,因为GIF是8位的,好看的png在GIF中变得有点模糊

下面是我使用的代码:

__author__ = 'Robert'
from images2gif import writeGif
from PIL import Image
import os

file_names = sorted((fn for fn in os.listdir('.') if fn.endswith('.png')))
#['animationframa.png', 'animationframb.png', 'animationframc.png', ...] "

images = [Image.open(fn) for fn in file_names]

print writeGif.__doc__
# writeGif(filename, images, duration=0.1, loops=0, dither=1)
#    Write an animated gif from the specified images.
#    images should be a list of numpy arrays of PIL images.
#    Numpy images of type float should have pixels between 0 and 1.
#    Numpy images of other types are expected to have values between 0 and 255.


#images.extend(reversed(images)) #infinit loop will go backwards and forwards.

filename = "my_gif.GIF"
writeGif(filename, images, duration=0.2)
#54 frames written
#
#Process finished with exit code 0

以下是26帧中的3帧:

缩小图像会减小尺寸:

size = (150,150)
for im in images:
    im.thumbnail(size, Image.ANTIALIAS)

Smart Manoj回答:从文件夹中的所有图像制作一个.mp4电影

安装:

pip install imageio-ffmpeg
pip install imageio

代码:

import os
import imageio

root = r'path_to_folder_with_images'

images = []    
for subdir, dirs, files in os.walk(root):
    for file in files:
        images.append(imageio.imread(os.path.join(root,file)))

savepath = r'path_to_save_folder'
imageio.mimsave(os.path.join(savepath,'movie.mp4'), images)

PS:确保你的“文件”列表按照你想要的方式排序,如果你已经相应地保存了你的图像,你会节省一些时间

老问题,有很多很好的答案,但可能仍然对另一种选择感兴趣……

我最近在github (https://github.com/WarrenWeckesser/numpngw)上发布的numpngw模块可以从numpy数组写入动画PNG文件。(更新:numpngw现在在pypi: https://pypi.python.org/pypi/numpngw。)

例如,这个脚本:

import numpy as np
import numpngw


img0 = np.zeros((64, 64, 3), dtype=np.uint8)
img0[:32, :32, :] = 255
img1 = np.zeros((64, 64, 3), dtype=np.uint8)
img1[32:, :32, 0] = 255
img2 = np.zeros((64, 64, 3), dtype=np.uint8)
img2[32:, 32:, 1] = 255
img3 = np.zeros((64, 64, 3), dtype=np.uint8)
img3[:32, 32:, 2] = 255
seq = [img0, img1, img2, img3]
for img in seq:
    img[16:-16, 16:-16] = 127
    img[0, :] = 127
    img[-1, :] = 127
    img[:, 0] = 127
    img[:, -1] = 127

numpngw.write_apng('foo.png', seq, delay=250, use_palette=True)

创建:

你需要一个支持动画PNG的浏览器(直接或带有插件)才能看到动画。

它不是一个python库,但mencoder可以做到这一点:从多个输入图像文件编码。你可以像这样从python中执行mencoder:

import os

os.system("mencoder ...")