Animated Gifs Are Only Transparent On Their First Frame (python Pil)
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 😁
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
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)"