# jch - hacked summer 2003 to read frames. # # The Python Imaging Library # $Id: gifmaker.py,v 1.1 2003/09/13 01:31:44 jch Exp $ # # convert sequence format to GIF animation # # history: # 97-01-03 fl created # # Copyright (c) Secret Labs AB 1997. All rights reserved. # Copyright (c) Fredrik Lundh 1997. # # See the README file for information on usage and redistribution. # import Image, ImageChops import string import ImagePalette from GifImagePlugin import getheader, getdata def bumpname(filename, pos): if pos == 0: pos = len(filename)-5 digit = string.find(string.digits, filename[pos]) #print "digit %d pos %d\n"%(digit, pos) if digit >= 0 and digit < 9: return filename[0:pos]+string.digits[digit+1]+filename[pos+1:len(filename)] elif digit == 9 and pos > 1: temp = filename[0:pos]+string.digits[0]+filename[pos+1:len(filename)] return bumpname(temp, pos-1) else: return "noway" # -------------------------------------------------------------------- # sequence iterator class image_sequence: def __init__(self, filename): self.filename = filename def __getitem__(self, ix): try: im = Image.open(self.filename) except IOError: print "can not open "+self.filename raise IndexError # end of sequence im.palette = self.palette tim = im.convert("P") tim.thumbnail((200,200)) self.filename = bumpname(self.filename, 0) print self.filename return tim def setPalette(self, palette): self.palette = palette # -------------------------------------------------------------------- # straightforward delta encoding def makedelta(fp, sequence): """Convert list of image frames to a GIF animation file""" frames = 0 previous = None for im in sequence: # # FIXME: write graphics control block before each frame if not previous: # global header for s in getheader(im) + getdata(im): fp.write(s) else: # delta frame delta = ImageChops.subtract_modulo(im, previous) bbox = delta.getbbox() if bbox: # compress difference for s in getdata(im.crop(bbox), offset = bbox[:2]): fp.write(s) else: # FIXME: what should we do in this case? pass previous = im.copy() frames = frames + 1 fp.write(";") return frames # -------------------------------------------------------------------- # main hack def compress(infile, outfile,palette): # open input image, and force loading of first frame im = Image.open(infile) # open output file fp = open(outfile, "wb") seq = image_sequence(infile) seq.setPalette(palette) makedelta(fp, seq) fp.close() if __name__ == "__main__": import sys if len(sys.argv) < 3: print "Usage: gifmaker frameNNNN.jpg outfile.gif [haspalette.gif]" print "concatenate all consecutive frames into a gif animation" sys.exit(1) palette = 0 if len(sys.argv) > 3: im = Image.open(sys.argv[3]) im.load() palette = im.palette compress(sys.argv[1], sys.argv[2], palette)