I want to open a GIF image from the python console in Linux. Normally when opening a .png
or .jpg
, I would do the following:
>>> from PIL import Image
>>> img = Image.open('test.png')
>>> img.show()
But if I do this:
>>> from PIL import Image
>>> img = Image.open('animation.gif')
>>> img.show()
Imagemagick will open but only show the first frame of the gif, not the animation.
Is there a way to show the animation of the GIF in a viewer in Linux?
Image.show
dumps the image to a temporary file and then tries to display the file. It calls ImageShow.Viewer.show_image
(see /usr/lib/python2.7/dist-packages/PIL/ImageShow.py
):
class Viewer:
def save_image(self, image):
# save to temporary file, and return filename
return image._dump(format=self.get_format(image))
def show_image(self, image, **options):
# display given image
return self.show_file(self.save_image(image), **options)
def show_file(self, file, **options):
# display given file
os.system(self.get_command(file, **options))
return 1
AFAIK, the standard PIL can not save animated GIfs1.
The image._dump
call in Viewer.save_image
only saves the first frame. So no matter what viewer is subsequently called, you only see a static image.
If you have Imagemagick's display
program, then you should also have its animate
program. So if you have the GIF as a file already, then you could use
animate /path/to/animated.gif
To do so from within Python, you could use the subprocess module (instead of img.show
):
import subprocess
proc = subprocess.Popen(['animate', '/path/to/animated.gif'])
proc.communicate()
1 According to kostmo, there is a script to save animated GIFS with PIL.
To show the animation without blocking the main process, use a separate thread to spawn the animate
command:
import subprocess
import threading
def worker():
proc = subprocess.Popen(['animate', '/path/to/animated.gif'])
proc.communicate()
t = threading.Thread(target = worker)
t.daemon = True
t.start()
# do other stuff in main process
t.join()