Skip to content

Instantly share code, notes, and snippets.

@codehwang
Forked from xyfeng/gif.py
Created November 28, 2017 08:32
Show Gist options
  • Save codehwang/0501551e66943e0683c49a3390cae787 to your computer and use it in GitHub Desktop.
Save codehwang/0501551e66943e0683c49a3390cae787 to your computer and use it in GitHub Desktop.

Revisions

  1. @xyfeng xyfeng renamed this gist Jul 13, 2015. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. @xyfeng xyfeng created this gist Jul 13, 2015.
    136 changes: 136 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,136 @@
    # From https://github.com/wnyc/PIL/blob/master/Scripts/gifmaker.py
    #
    # The Python Imaging Library
    # $Id$
    #
    # 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.
    #

    #
    # For special purposes, you can import this module and call
    # the makedelta or compress functions yourself. For example,
    # if you have an application that generates a sequence of
    # images, you can convert it to a GIF animation using some-
    # thing like the following code:
    #
    # import Image
    # import gifmaker
    #
    # sequence = []
    #
    # # generate sequence
    # for i in range(100):
    # im = <generate image i>
    # sequence.append(im)
    #
    # # write GIF animation
    # fp = open("out.gif", "wb")
    # gifmaker.makedelta(fp, sequence)
    # fp.close()
    #
    # Alternatively, use an iterator to generate the sequence, and
    # write data directly to a socket. Or something...
    #

    from PIL import Image, ImageChops
    import string

    from PIL.GifImagePlugin import getheader, getdata

    # --------------------------------------------------------------------
    # sequence iterator

    class image_sequence:
    def __init__(self, im):
    self.im = im
    def __getitem__(self, ix):
    try:
    if ix:
    self.im.seek(ix)
    return self.im
    except EOFError:
    raise IndexError # end of sequence

    # --------------------------------------------------------------------
    # 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):

    # open input image, and force loading of first frame
    im = Image.open(infile)
    im.load()

    # open output file
    fp = open(outfile, "wb")

    seq = image_sequence(im)

    makedelta(fp, seq)

    fp.close()


    if __name__ == "__main__":

    import sys

    if len(sys.argv) < 3:
    print "GIFMAKER -- create GIF animations"
    print "Usage: gifmaker infile outfile"
    sys.exit(1)

    compress(sys.argv[1], sys.argv[2])