我有一系列的图片,我想从中创建一个视频。理想情况下,我可以为每帧指定帧持续时间,但固定的帧速率也可以。我在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)

其他回答

from PIL import Image
import glob  #use it if you want to read all of the certain file type in the directory
imgs=[]
for i in range(596,691): 
    imgs.append("snap"+str(i)+'.png')
    print("scanned the image identified with",i)  

标识不同文件名的索引的起始值和结束值+1

imgs = glob.glob("*.png") #do this if you want to read all files ending with .png

我的文件是:snap596.png, snap597.png ......snap690.png

frames = []
for i in imgs:
    new_frame = Image.open(i)
    frames.append(new_frame)

保存到一个GIF文件,永远循环

frames[0].save('fire3_PIL.gif', format='GIF',
    append_images=frames[1:],
    save_all=True,
    duration=300, loop=0)

我发现闪烁的问题与imageio和这个方法固定。

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

我最近在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的浏览器(直接或带有插件)才能看到动画。

安装

pip install imageio-ffmpeg
pip install imageio

Code

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

当保存为mp4而不是gif时,质量提高,大小从8Mb减少到80Kb

真是不可思议……所有人都提出了一些特殊的包来播放动画GIF,目前它可以用Tkinter和经典的PIL模块!

这是我自己的GIF动画方法(我之前创建的)。非常简单:

from Tkinter import * 
from PIL import Image, ImageTk
from time import sleep

def stop(event):
  global play
  play = False
  exit() 

root = Tk()
root.bind("<Key>", stop) # Press any key to stop
GIFfile = {path_to_your_GIF_file}    
im = Image.open(GIFfile); img = ImageTk.PhotoImage(im)
delay = float(im.info['duration'])/1000; # Delay used in the GIF file 
lbl = Label(image=img); lbl.pack() # Create a label where to display images
play = True; frame = 0
while play:
  sleep(delay);
  frame += 1
  try:
    im.seek(frame); img = ImageTk.PhotoImage(im)
    lbl.config(image=img); root.update() # Show the new frame/image
  except EOFError:
    frame = 0 # Restart

root.mainloop()

您可以设置自己的方法来停止动画。如果你想要完整版本的播放/暂停/退出按钮,请告诉我。

注意:我不确定连续帧是从内存还是从文件(磁盘)读取的。在第二种情况下,如果它们都一次读取并保存到一个数组(列表)中,那么效率会更高。(我没兴趣知道!:)

使用windows7, python2.7, opencv 3.0,以下工作为我:

import cv2
import os

vvw           =   cv2.VideoWriter('mymovie.avi',cv2.VideoWriter_fourcc('X','V','I','D'),24,(640,480))
frameslist    =   os.listdir('.\\frames')
howmanyframes =   len(frameslist)
print('Frames count: '+str(howmanyframes)) #just for debugging

for i in range(0,howmanyframes):
    print(i)
    theframe = cv2.imread('.\\frames\\'+frameslist[i])
    vvw.write(theframe)