Skip to content Skip to sidebar Skip to footer

Animated Gifs Are Only Transparent On Their First Frame (python Pil)

The following code creates a GIF from two images: # GIFs are always palette images so they would be converted later anyway im1 = PIL.Image.open('grin-emoji-by-twitter-rgba.png').co

Solution 1:

Yes, there is a way. We can manually edit the color palette to move transparency from index 255 to 0.save will not misbehave if transparency is at index 0 instead of 255.

I accomplished this by right-shifting the whole color-palette by one index, so index 5 becomes index 6, index 255 becomes index 0, and so on.

In the worst case (e.g. long colorful GIF) the transparency is NOT always at index 255 and we have to manually align it to index 0 (see shiftme line).

im1 = PIL.Image.open('grin-emoji-by-twitter-rgba.png').convert('P')
im2 = PIL.Image.open('grin-emoji-by-twitter-rgba-2.png').convert('P')

p1 = im1.getpalette()
p2 = im2.getpalette()

# if you know a data point in the resulting image that will be# transparent you can also set it directly e.g. 'shiftme = -frame[0][0]'
shiftme = 1       
im1 = (numpy.array(im1) + shiftme) % 256# shift data pointing into palette
im2 = (numpy.array(im2) + shiftme) % 256

im1 = PIL.Image.fromarray( im1 ).convert('P')
im2 = PIL.Image.fromarray( im2 ).convert('P')

im1.putpalette( p1[-3*shiftme:] + p1[:-3*shiftme] )  # shift palette
im2.putpalette( p2[-3*shiftme:] + p2[:-3*shiftme] )  # NB this is NOT '-4' as it is RGB not RGBAprint(numpy.array(im1))
print(numpy.array(im2))

im1.save('output.gif', save_all=True, append_images=[im2, im1, im2], loop=0, duration=200, transparency=0)

Result 😁

enter image description here

Solution 2:

As an alternative to my other answer, you can also just set the disposal value to 2:

im1.save('output.gif', save_all=True, append_images=[im2, im1, im2], 
         loop=0, duration=200, transparency=255, disposal=2)

Note that unlike my other answer this does not work 100% of the time, as the transparency channel can jump around to other indexes. :-/ This only seems to happen in longer GIFs with many colors in them however.

Left: This answer, Right: Other answer with manual alignment

example of bug persistingexample of bug fixed

Edit: Here it's claimed this got fixed in newer versions of pillow! (I think 8.1.2+)

Post a Comment for "Animated Gifs Are Only Transparent On Their First Frame (python Pil)"