I'm having the same exact problem as #634 but that issue was "fixed".

When I seperate the frames using convert -coalesce animation.gif target.png in ImageMagick, the frames come out looking perfect, but with pillow...
import PIL
import PIL.Image
i = PIL.Image.open('test.gif')
i.show() # correct image displays on left
i.seek(i.tell() + 1)
i.show() # image is incorrect on right
Just to check before going any further - you've mixed up left and right in your comments, yes?
Oh, yeah @radarhere. Note to self: do not open issues while sleepy.
Thanks for clarifying, and thanks for the link to the previous issue, very helpful.
So, GIFs can have a 'disposal method', and one setting of this that each subsequent frame is to be pasted on top of a previous one, making the raw latter frame simply the difference of the image. Sounds like a good compression technique. So the second frame is an RGBA to be pasted onto the first one.
The good news is that the GifImagePlugin is correctly working all of this out and performing those operations. The bad news is that it's the paste operation that is exhibiting the bug. If I use PIL to save the raw first frame and second frame images and overlay them using an external program, it works fine. If I get PIL to paste them together, then the problematic image is generated.
That's all I have for the moment, but it's a start.
Okay! It's because the base image is P mode, whereas the mask is RGBA. Convert the base image to RGB, and it works fine.
So that's how to get it working. I'm not quite sure what the best solution is. If the aim was to fix this from GifImagePlugin, then it would be simpler. However, I presume it is better to solve this for the paste method.
The convert method returns a copy. I'm not sure if there is a way for an image to easily convert itself.
Convert the base image to RGB, and it works fine.
I'm sorry, I don't understand what you mean. Convert the charmander.gif into RGB?
If I use PIL to save the raw first frame and second frame images and overlay them using an external program
also, how do you save the second frame? I'm really sorry I kinda abandoned this, I looked at it and forgot. Then once I got to my problem again I remembered.
--- a/PIL/GifImagePlugin.py
+++ b/PIL/GifImagePlugin.py
@@ -281,6 +281,9 @@ class GifImageFile(ImageFile.ImageFile):
# we do this by pasting the updated area onto the previous
# frame which we then use as the current image content
updated = self.im.crop(self.dispose_extent)
+ if self._prev_im.mode == "P":
+ self._prev_im = self._prev_im.convert("RGBA")
+ updated = updated.convert("RGBA")
self._prev_im.paste(updated, self.dispose_extent,
updated.convert('RGBA'))
self.im = self._prev_im
If you adjust your Pillow installation according to the above diff, then your program should run correctly. That will solve your immediate problem.
Thank you, but is there anyway to do it within the code so that people can use it without the fix.
I don't know how to resolve the bug within the Pillow code. Hopefully this problem will be resolved by someone, and contributions are welcome if you have suggestions.
I thought that you were seeking an immediate solution to your problem, and that was my attempt at one.
I was, but my problem exists for my program that a lot of people use and I want it to be fixed for everyone without people having to apply a fix, I will continue to see if this can be fixed within pillow, maybe making an external paste method. Thank you so much for your help. I really appreciate it
hi @radarhere
You patch works, why didn't you merge it ?
Hi. My patch works, but with two problems -
GifImagePlugin, but is a bug when pasting a transparent image.If you want to create a PR with the patch, to see if others agree with you that it should be merged, you're welcome to.
This is still an issue
This is still an issue

馃憤 Having this issue as well but in a different way.
I have a GIF with disposal method set to 1 as well. But the previous frame uses the global color table and the new frame uses a local color table. When pasting the new image on the previous image, the color table for the local color table is not preserved.
@addisonElliott to keep tracking simple, I'd ask that you create a new issue for your problem, since it is not exactly the same as this one.
Hi, @radarhere . I stumbled across the same issue and tried your workaround code. I am using PIL 5.2.0 in the simplest loop to show every frame.
But it throws this error:
Traceback (most recent call last):
......
File "C:\Users\hujas\AppData\Local\Programs\Python\Python36\lib\site-packages\PIL\ImageFile.py", line 138, in load
pixel = Image.Image.load(self)
File "C:\Users\hujas\AppData\Local\Programs\Python\Python36\lib\site-packages\PIL\Image.py", line 822, in load
self.im.putpalette(*self.palette.getdata())
ValueError: unrecognized image mode
Also, only the first two frames can be shown correctly, so this leads me to think that PIL is now getting the palette from the previous frame and feeding it to the next frame when load() is called on the next frame.
Apparently self.palette.getdata() doesn't support RGBA mode? So I modified your code like this:
self._prev_im.paste(updated, self.dispose_extent, updated.convert('RGBA'))
# I added this following line
self._prev_im=self._prev_im.convert('P')
self.im = self._prev_im
self._prev_im = self.im.copy()
And then every frame comes out as expected.
The real problem does not exist within GifImagePlugin, but is a bug when pasting a transparent image.
I don't think there's a bug with pasting a transparent image, since it's using the paste() method of Image class. I skimmed through the paste() method and saw this:
if self.mode != im.mode:
if self.mode != "RGB" or im.mode not in ("RGBA", "RGBa"):
im = im.convert(self.mode)
So the updated area will be converted to the same mode as the frame(in this case, 'P'). This is probably the reason why transparency went missing. It's more like an incompatibility rather than a bug that can be fixed in the paste() method. A very strong fix would be writing a new paste() and override for GIF images, but I think your workaround is perfectly fine as a general fix.