我有一系列的图片,我想从中创建一个视频。理想情况下,我可以为每帧指定帧持续时间,但固定的帧速率也可以。我在wxPython中这样做,所以我可以渲染到wxDC或我可以将图像保存到文件,如PNG。是否有一个Python库,将允许我创建一个视频(AVI, MPG等)或一个动画GIF从这些帧?
编辑:我已经尝试过PIL,它似乎不起作用。有人能用这个结论来纠正我吗?这个链接似乎支持我关于PIL的结论:http://www.somethinkodd.com/oddthinking/2005/12/06/python-imaging-library-pil-and-animated-gifs/
就像沃伦去年说的,这是一个老问题。由于人们似乎仍然在浏览页面,我想将他们重定向到一个更现代的解决方案。就像blakev说的,github上有一个枕头的例子。
import ImageSequence
import Image
import gifmaker
sequence = []
im = Image.open(....)
# im is your original image
frames = [frame.copy() for frame in ImageSequence.Iterator(im)]
# write GIF animation
fp = open("out.gif", "wb")
gifmaker.makedelta(fp, frames)
fp.close()
注意:这个例子已经过时了(gifmaker不是一个可导入的模块,只是一个脚本)。Pillow有一个GifImagePlugin(其源代码在GitHub上),但ImageSequence上的文档似乎表明有限的支持(只读)
真是不可思议……所有人都提出了一些特殊的包来播放动画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()
您可以设置自己的方法来停止动画。如果你想要完整版本的播放/暂停/退出按钮,请告诉我。
注意:我不确定连续帧是从内存还是从文件(磁盘)读取的。在第二种情况下,如果它们都一次读取并保存到一个数组(列表)中,那么效率会更高。(我没兴趣知道!:)
截至2009年6月,最初引用的博客文章在评论中有一个创建动画动图的方法。下载脚本images2gif.py(以前是images2gif.py,更新由@geographika提供)。
然后,要反转gif中的帧,例如:
#!/usr/bin/env python
from PIL import Image, ImageSequence
import sys, os
filename = sys.argv[1]
im = Image.open(filename)
original_duration = im.info['duration']
frames = [frame.copy() for frame in ImageSequence.Iterator(im)]
frames.reverse()
from images2gif import writeGif
writeGif("reverse_" + os.path.basename(filename), frames, duration=original_duration/1000.0, dither=0)
下面是如何使用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
我偶然发现了PIL的ImageSequence模块,它提供了更好(更标准)的GIF动画。这次我也使用了Tk的after()方法,这比time.sleep()更好。
from Tkinter import *
from PIL import Image, ImageTk, ImageSequence
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 = im.info['duration'] # Delay used in the GIF file
lbl = Label(image=img); lbl.pack() # Create a label where to display images
play = True;
while play:
for frame in ImageSequence.Iterator(im):
if not play: break
root.after(delay);
img = ImageTk.PhotoImage(frame)
lbl.config(image=img); root.update() # Show the new frame/image
root.mainloop()