2

Possible Duplicate:
Python: Converting GIF frames to PNG

I tried to load the frames of a GIF animation with PIL, but got funny results. The first frame loaded fine, but all the rest contained wrong data. On my original image, they looked "grayed out", and in the test image I use here, they just look black. I'm guessing it is caused by the palette indexes being used directly as the color value for each component.

I seem to get the correct data for the first frame I look at, and incorrect data for the others. Ie. if I seek to the second frame without looking at the first one, I get the correct data for that one instead. By using that, I can work around the problem by re-opening the image between each frame and seeking to the next frame in the newly opened image instead.

This seems to only happen if I'm using im.convert(), ie. when moving away from the indexed color model of the GIF. It is triggered even when using im.copy() though, so even if I just use that on the first frame, the second one then has the wrong data after using im.convert().

Is this a bug in PIL, or am I just doing something horribly, horribly wrong? The workaround I have is a really ugly hack, is there a better way to work around this?

Here's a snippet that illustrates the issue: (It writes the test image as rgb.gif to the current working directory)

import binascii
import Image    

# Create the test image file
path = 'rgb.gif'
with file(path, 'wb') as f:
        f.write(binascii.a2b_base64('R0lGODlhCAAIAKEDAAAA//8AAAD/AP///yH'
            '/C05FVFNDQVBFMi4wAwEAAAAh+QQJZAADACwAAAAACAAIAAACC5yPiRHJvJ'
            '5rqqYCACH5BAlkAAMALAAAAAAIAAgAAAILnI+JIsm8nmuqpgIAIfkECWQAA'
            'wAsAAAAAAgACAAAAgucj4kAybyea6qmAgA7'
        ))

# Look at frame 0, then load frame 1
im = Image.open(path)
test1_frame0 = im.copy()
im.seek(1)
# im.convert() returns a new image but I'm using im.copy() to
# make it clear this shouldn't affect the original image
test1_frame1 = im.copy().convert('RGBA').tostring()

# Load frame 1 without looking at frame 0 first
im = Image.open(path)
im.seek(1)
test2_frame1 = im.copy().convert('RGBA').tostring()

# Result is not equal, ie. just doing im.copy() on the first frame
# alters the second frame    
print test1_frame1 == test2_frame1

I'm using PIL 1.1.7.

Community
  • 1
  • 1
Aleksi Torhamo
  • 6,452
  • 2
  • 34
  • 44

1 Answers1

1

Just after I posted this, I noticed this on the sidebar, so apparently it's a bug.

Community
  • 1
  • 1
Aleksi Torhamo
  • 6,452
  • 2
  • 34
  • 44