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

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


当前回答

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

其他回答

现在我在用ImageMagick。我将帧保存为PNG文件,然后从Python中调用ImageMagick的convert.exe来创建一个动画GIF。这种方法的好处是我可以为每一帧单独指定帧持续时间。不幸的是,这取决于ImageMagick安装在机器上。他们有一个Python包装器,但它看起来很糟糕,不受支持。还在考虑其他建议。

真是不可思议……所有人都提出了一些特殊的包来播放动画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()

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

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

下面是如何使用PIL (install with: pip install Pillow):

import glob
import contextlib
from PIL import Image

# filepaths
fp_in = "/path/to/image_*.png"
fp_out = "/path/to/image.gif"

# use exit stack to automatically close opened images
with contextlib.ExitStack() as stack:

    # lazily load images
    imgs = (stack.enter_context(Image.open(f))
            for f in sorted(glob.glob(fp_in)))

    # extract  first image from iterator
    img = next(imgs)

    # https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#gif
    img.save(fp=fp_out, format='GIF', append_images=imgs,
             save_all=True, duration=200, loop=0)

查看文档:https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#gif

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和这个方法固定。

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

import os

os.system("mencoder ...")