[PYTHON IMAGE-SIG] GIF animations in Grail
Fred L. Drake
fdrake@CNRI.Reston.Va.US
Fri, 4 Apr 1997 14:19:47 -0500 (EST)
Here's a filetype handler for Grail that does GIF animations for GIF
files loaded as documents; this doesn't handle "in-line" GIFs.
(Sorry!)
Save this as ~/.grail/filetypes/image_gif.py, and make sure the file
Grail/pil_interface.py from the PIL distribution is available for
Grail (it can be placed in the same directory).
-Fred
--
Fred L. Drake, Jr.
fdrake@cnri.reston.va.us
Corporation for National Research Initiatives
1895 Preston White Drive
Reston, VA 20191-5434
===========================================================================
# Grail interface to PIL, with support for animated GIFs.
import grailutil
import Image
import ImageTk
import pil_interface
import string
import StringIO
import sys
import Tkinter
class parse_image_gif(pil_interface.pil_interface):
im = None
currentpos = 0
duration = 0
loop = 0
def close(self):
if self.buf:
try:
self.label.config(text="<decoding>")
self.label.update_idletasks()
self.buf = string.joinfields(self.buf, "")
self.im = im = Image.open(StringIO.StringIO(self.buf))
im.load() # benchmark decoding
self.tkim = tkim = ImageTk.PhotoImage(im.mode, im.size)
tkim.paste(im)
self.label.image = tkim.image
self.label.config(image=self.label.image)
if im.info.has_key("duration"):
self.duration = im.info["duration"]
if im.info.has_key("loop"):
self.duration = self.duration or 100
self.loop = im.info["loop"]
if self.duration or self.loop:
self.viewer.register_reset_interest(self.cancel_loop)
self.after_id = self.label.after(self.duration,
self.next_image)
except:
self.broken = 1
stdout = sys.stdout
try:
sys.stdout = sys.stderr
print "Error decoding image:"
print sys.exc_type + ":", sys.exc_value
finally:
sys.stdout = stdout
if self.broken:
self.label.image = Tkinter.PhotoImage(
file=grailutil.which(ERROR_FILE))
self.label.config(image = self.label.image)
self.viewer.text.insert(Tkinter.END, '\nBroken Image!')
def next_image(self):
newpos = self.currentpos + 1
try:
self.im.seek(newpos)
except (ValueError, EOFError):
self.viewer.unregister_reset_interest(self.cancel_loop)
return # ignore looping for now....
self.currentpos = newpos
self.tkim.paste(self.im)
self.after_id = self.label.after(self.duration, self.next_image)
def cancel_loop(self, *args):
self.viewer.unregister_reset_interest(self.cancel_loop)
self.label.after_cancel(self.after_id)
_______________
IMAGE-SIG - SIG on Image Processing with Python
send messages to: image-sig@python.org
administrivia to: image-sig-request@python.org
_______________