imageio - python make gif
¿Produce programáticamente video o GIF animado en Python? (16)
Tengo una serie de imágenes de las que quiero crear un video. Idealmente, podría especificar una duración de fotograma para cada fotograma, pero también sería adecuada una velocidad de fotogramas fija. Estoy haciendo esto en wxPython, así que puedo renderizar en wxDC o puedo guardar las imágenes en archivos, como PNG. ¿Hay una biblioteca de Python que me permita crear un video (AVI, MPG, etc.) o un GIF animado a partir de estos marcos?
Editar: Ya he probado PIL y parece que no funciona. ¿Alguien puede corregirme con esta conclusión o sugerir otro juego de herramientas? Este enlace parece respaldar mi conclusión con respecto a PIL: http://www.somethinkodd.com/oddthinking/2005/12/06/python-imaging-library-pil-and-animated-gifs/
¿Has probado PyMedia ? No estoy 100% seguro, pero parece que este ejemplo tutorial apunta a su problema.
A partir de junio de 2009, la publicación de blog originalmente citada tiene un método para crear GIF animados en los comentarios . Descargue el script images2gif.py (anteriormente images2gif.py , actualización cortesía de @geographika).
Luego, para invertir los cuadros en un gif, por ejemplo:
#!/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)
Acabo de probar lo siguiente y fue muy útil:
Primero descargue las bibliotecas Figtodat
e images2gif
a su directorio local.
En segundo lugar, recoge las figuras en una matriz y conviértelas en un gif animado:
import sys
sys.path.insert(0,"/path/to/your/local/directory")
import Figtodat
from images2gif import writeGif
import matplotlib.pyplot as plt
import numpy
figure = plt.figure()
plot = figure.add_subplot (111)
plot.hold(False)
# draw a cardinal sine plot
images=[]
y = numpy.random.randn(100,5)
for i in range(y.shape[1]):
plot.plot (numpy.sin(y[:,i]))
plot.set_ylim(-3.0,3)
plot.text(90,-2.5,str(i))
im = Figtodat.fig2img(figure)
images.append(im)
writeGif("images.gif",images,duration=0.3,dither=0)
Bueno, ahora estoy usando ImageMagick. Guardo mis marcos como archivos PNG y luego invoco el convert.exe de ImageMagick desde Python para crear un GIF animado. Lo bueno de este enfoque es que puedo especificar una duración de fotograma para cada fotograma individualmente. Desafortunadamente, esto depende de que ImageMagick esté instalado en la máquina. Tienen un contenedor de Python, pero se ve bastante mal y no es compatible. Todavía abierto a otras sugerencias.
Como dijo Warren el año pasado , esta es una vieja pregunta. Dado que las personas parecen estar viendo la página, me gustaría redirigirlas a una solución más moderna. Como dijo blakev here , hay un ejemplo de Pillow en 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()
Nota: Este ejemplo no está actualizado ( gifmaker
no es un módulo importable, solo un script). Pillow tiene un GifImagePlugin (cuya fuente está en GitHub ), pero el documento en ImageSequence parece indicar soporte limitado (solo lectura)
Con windows7, python2.7, opencv 3.0, lo siguiente funciona para mí:
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)
Encontré el módulo ImageSequence de PIL, que ofrece una mejor (y más estándar) anotación de GIF. También uso el método after () de Tk esta vez, que es mejor que 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()
Es realmente increíble ... ¡Todos proponen un paquete especial para jugar un GIF animado, en el momento en que se puede hacer con Tkinter y el clásico módulo PIL!
Aquí está mi propio método de animación GIF (lo creé hace un tiempo). Muy simple:
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()
Puede configurar sus propios medios para detener la animación. Avíseme si desea obtener la versión completa con los botones Reproducir / Pausa / Salir.
Nota: No estoy seguro de si los cuadros consecutivos se leen desde la memoria o desde el archivo (disco). En el segundo caso, sería más eficiente si todos leen a la vez y guardan en una matriz (lista). (¡No estoy tan interesado en saberlo! :)
Estaba buscando un código de línea único y encontré lo siguiente para trabajar para mi aplicación. Aquí esta lo que hice:
Primer paso: Instale ImageMagick desde el siguiente enlace
https://www.imagemagick.org/script/download.php
Segundo paso: apunte la línea del cmd a la carpeta donde se colocan las imágenes (en mi caso, formato .png)
Tercer paso: escriba el siguiente comando
magick -quality 100 *.png outvideo.mpeg
Gracias FogleBird por la idea!
La tarea se puede completar ejecutando el script de dos líneas de python desde la misma carpeta que la secuencia de archivos de imágenes. Para archivos con formato png, el script es:
from scitools.std import movie
movie(''*.png'',fps=1,output_file=''thisismygif.gif'')
Lo más fácil que hace que funcione para mí es llamar a un comando de shell en Python.
Si sus imágenes están almacenadas como dummy_image_1.png, dummy_image_2.png ... dummy_image_N.png, entonces puede usar la función:
import subprocess
def grid2gif(image_str, output_gif):
str1 = ''convert -delay 100 -loop 1 '' + image_str + '' '' + output_gif
subprocess.call(str1, shell=True)
Simplemente ejecuta:
grid2gif("dummy_image*.png", "my_output.gif")
Esto construirá su archivo gif my_output.gif.
No es una biblioteca de Python, pero el mencoder puede hacer eso: Codificación desde múltiples archivos de imagen de entrada . Puede ejecutar mencoder desde python de esta manera:
import os
os.system("mencoder ...")
Para crear un video, puedes usar opencv ,
#load your frames
frames = ...
#create a video writer
writer = cvCreateVideoWriter(filename, -1, fps, frame_size, is_color=1)
#and write your frames in a loop if you want
cvWriteFrame(writer, frames[i])
Recomiendo no usar images2gif de visvis porque tiene problemas con PIL / Pillow y no se mantiene activamente (lo sé, porque yo soy el autor).
En su lugar, utilice imageio , que fue desarrollado para resolver este problema y más, y está destinado a permanecer.
Solución rápida y sucia:
import imageio
images = []
for filename in filenames:
images.append(imageio.imread(filename))
imageio.mimsave(''/path/to/movie.gif'', images)
Para películas más largas, use el enfoque de transmisión por secuencias:
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)
Una vieja pregunta, muchas buenas respuestas, pero aún podría haber interés en otra alternativa ...
El módulo numpngw
que puse recientemente en github ( https://github.com/WarrenWeckesser/numpngw ) puede escribir archivos PNG animados de matrices numpy. ( Actualización : numpngw
ahora está en pypi: https://pypi.python.org/pypi/numpngw .)
Por ejemplo, este script:
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)
Crea:
Necesitará un navegador que admita PNG animado para ver la animación. Firefox lo hace, Safari no, y Chrome tiene un plugin para ello.
images2gif.py que era fácil de usar. Sin embargo, parece duplicar el tamaño del archivo ...
26 archivos PNG de 110kb, esperaba 26 * 110kb = 2860kb, pero mi_gif.GIF era de 5.7mb
También porque el GIF era de 8 bits, el agradable png se volvió un poco borroso en el GIF
Aquí está el código que utilicé:
__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
Aquí hay 3 de los 26 cuadros:
la reducción de las imágenes redujo el tamaño:
size = (150,150)
for im in images:
im.thumbnail(size, Image.ANTIALIAS)