New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GIF frames: background, transparency, combining #4640
Comments
@Dragorn421 you might want to look into #4644 |
My issue is about loading gifs, not saving them, although in those tests I did you can indeed see gifs in Pillow hate transparency. Still, thanks |
My experience is if you convert a 'P' image to an RGBA, you get proper alpha values, except for when not (see also the issue for it). Did you try your gifs with my processor? Also, in my experience, only the |
See your issue for discussing your processor |
Until a proper fix I guess you can use what I posted on stackoverflow https://stackoverflow.com/questions/61958291/gifs-read-with-pillow-have-black-borders under "EDIT 2:" |
yeah, I have tested your "EDIT 2" on stackouverflow and test your "EDIT 3" on github, but I still get other background color |
Any solutions guys? I'm getting the same error results on large gifs with more colors. After the first frame all frames are getting black background. Code: gif = Image.open("gif4.GIF")
duration = 100
disposal = 2
frames = []
ind = 0
for frame in ImageSequence.Iterator(gif):
bg2 = Image.open('test1.png')
bg2.paste(frame, frame.convert('RGBA'))
bg2.save('{}.png'.format(ind))
frames.append(bg2)
ind += 1
frames[0].save('test.gif', save_all=True, append_images=frames[1:], loop=0, optimise=False, duration=duration, disposal=disposal, format='GIF') Frames: |
I have the exact same issue as above: from PIL import Image, ImageSequence, GifImagePlugin
import os
bg = Image.open('images/bg/Background Sky.gif')
body = Image.open('images/body/Body Blue.gif')
eyes = Image.open('images/eyes/Eyes Green.gif')
headwear = Image.open('images/headwear/Headwear Party Hat.gif')
frames = []
for idx, frame in enumerate(ImageSequence.Iterator(bg)):
frame = Image.new('RGBA', (640, 640), color=(255,0,0,0))
frame.paste(ImageSequence.Iterator(bg)[idx])
frame.paste(ImageSequence.Iterator(body)[idx], mask=ImageSequence.Iterator(body)[idx].convert("RGBA"))
frame.paste(ImageSequence.Iterator(eyes)[idx], mask=ImageSequence.Iterator(eyes)[idx].convert("RGBA"))
frame.paste(ImageSequence.Iterator(headwear)[idx], mask=ImageSequence.Iterator(headwear)[idx].convert("RGBA"))
frames.append(frame)
print(frames)
#frames[0].save('images/generated/output.gif', save_all=True, append_images=frames[0:])
frames[0].save('images/generated/output.gif', save_all=True, append_images=frames[1:], loop=0) |
The issue from @tomhaydn became #5837 and the issue from @AnasYasin became #5755 |
With #5857, the PNGs look correct. |
Those PRs have been merged, so this should be fixed in Pillow 9.0, due to be released on January 2. |
This was originally a question on StackOverflow, but I since think it's more of a Pillow bug/limitation, I will put all relevant information here, no need to read the SO post.
Resources:
PepePls.gif
PeepoCreepo.gif
With PepePls.gif:
With PeepoCreepo.gif:
(I would shorten the gifs if I knew how to recreate their features, but I don't)
Black borders
The first thing you notice is that there are black borders everywhere. After researching and reading through GifImagePlugin.py, I think this is because in
disposal_method==2
(which I think is "replace" whole frame) the load-image code (which I didn't locate precisely, I guess it's C somewhere?) pastes to a new image only thedispose_extent
part of a frame which is the part read from the file (aka the part in the middle of the black borders). So that's fine but I guess the "new image" which is being pasted on is likely initialized wrongly, since black seems to be the default color in Pillow it may not be initialized at all.I fixed this by copying the
dispose_extent
part onto a fully transparent image, but I'm not sure how to detected if the gif should be read that way (how to tell if it wants a transparent background?), code:Apart from png_f2.png from PeepoCreepo.gif (no idea what is happening there either), all the black borders have disappeared when saving to png.
gif and rgba
I'm not sure why
.convert(rgba).save(gif)
makes the saved image file lose transparency. Didn't research that issue at all.frame combine
Let's zoom in on the rgba_png_fX.png files, because I'm sure they went unnoticed among the hundreds of frames I dumped:
Notice rgba_png_f2.png has missing pixels
Here's a screenshot of GIMP (image manipulation program) with those frames which may help understand the issue:
Notice how in GIMP frame "Image vidéo 3" (which corresponds to our rgba_png_f2.png file) is "combine"
However if you add
print(image.__dict__.get('disposal_method', None))
at the beginning of thewhile True:
loop you'll getI assume 1 is "combine" (at time of writing) and 2 is "replace" (at time of writing)
So, Pillow is using the
disposal_method
value early? If it was delayed by a frame, rgba_png_f2.png would be correctly overlayed on rgba_png_f1.pngmy full "debugging" script (can be ignored)
For reference, here's a script with a lot of useless stuff which I used for debugging, it does highlight what undocumented
GifImageFile
members seem to be relevant here though. It also fixes the "delay combine" issue with a local variable disposal_method_lastThe text was updated successfully, but these errors were encountered: