make imageio python video wxpython animated-gif

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/



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.



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)