4

Is there any way to display an animated GIF in Tkinter using Python Image Library?

I thought the ImageSequence module would be the way to do it, but I don't know how to use it and if it's possible.

The first question is if there is any easy way. For example: load a GIF using PIL and the ImageSequence and just draw it on a Tkinter window using ImageTk.PhotoImage and it will be animated.

Or do I have to set up a function myself, using the after method or something like time.sleep to loop through the GIF frames and draw them on a tkinter window?

The second question: even if I have to make a function to loop through the GIF frames, is the ImageSequence module supposed to do this or PIL has another module for it?

I'm using Python 3.1 and a private port of PIL, indicated in this topic.

Community
  • 1
  • 1
Marcos Saito
  • 530
  • 2
  • 10
  • 17

2 Answers2

6

Newsgroups: comp.lang.python

From: "Fredrik Lundh"

Date: Mon, 1 May 2006

Daniel Nogradi wrote:

'The source distribution of the 1.1.4 version comes with a Scripts directory where you can find player.py, gifmaker.py and explode.py which all deal with animated gif.'

they're still shipped with 1.1.5 (and 1.1.6), and they should work.

if all you're missing is a few files from the script directory, you can get them here:

http://svn.effbot.org/public/pil/Scripts/


player.py is run from the command line

see if this one works for you:

from Tkinter import * 
from PIL import Image, ImageTk


class MyLabel(Label):
    def __init__(self, master, filename):
        im = Image.open(filename)
        seq =  []
        try:
            while 1:
                seq.append(im.copy())
                im.seek(len(seq)) # skip to next frame
        except EOFError:
            pass # we're done

        try:
            self.delay = im.info['duration']
        except KeyError:
            self.delay = 100

        first = seq[0].convert('RGBA')
        self.frames = [ImageTk.PhotoImage(first)]

        Label.__init__(self, master, image=self.frames[0])

        temp = seq[0]
        for image in seq[1:]:
            temp.paste(image)
            frame = temp.convert('RGBA')
            self.frames.append(ImageTk.PhotoImage(frame))

        self.idx = 0

        self.cancel = self.after(self.delay, self.play)

    def play(self):
        self.config(image=self.frames[self.idx])
        self.idx += 1
        if self.idx == len(self.frames):
            self.idx = 0
        self.cancel = self.after(self.delay, self.play)        


root = Tk()
anim = MyLabel(root, 'animated.gif')
anim.pack()

def stop_it():
    anim.after_cancel(anim.cancel)

Button(root, text='stop', command=stop_it).pack()

root.mainloop()
Keith Hall
  • 15,362
  • 3
  • 53
  • 71
noob oddy
  • 1,314
  • 8
  • 11
  • Thanks but, I'm a bit new to Python, how do I actually use the script? I've imported tkinter, PIL and player, and already opened the image, I've tried `animation = player.UI(root, im)` and some variations. Is the UI class in the player script a Label? When I try to pack() it, it says "UI object has no attribute tk", and if I don't pack() or grid(), nothing happens. – Marcos Saito Nov 03 '11 at 13:05
0

Simple PIL version:

canvas = Image.new("RGB",(Width,Height),"white")
gif = Image.open('text.gif', 'r')
frames = []
try:
    while 1:
        frames.append(gif.copy())
        gif.seek(len(frames))
except EOFError:
    pass

for frame in frames:
     canvas.paste(frame)
     canvas.show()
Mike Redrobe
  • 1,248
  • 13
  • 12