-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
GifImageFile and animated gif with mismatched color palettes #2893
Copy link
Copy link
Closed
Labels
BugAny unexpected behavior, until confirmed feature.Any unexpected behavior, until confirmed feature.GIF
Milestone
Description
I'm trying to resize an animated gif file with a different color palette for each frame.
Each frame should be composed with own colors, but because of buildin frames merge (see GifImageFile.load_end) colors are messed up.
Python: 3.6
PIL: 4.4.0.dev0
from PIL import Image
source = Image.open("src.gif")
w, h = source.size
resized = []
try:
for i in range(0, 0xffffffff):
source.seek(i)
resized.append(source.convert('RGBA').resize((w//2, h//2), Image.ANTIALIAS))
except EOFError:
pass
resized[0].save("result.gif", "GIF", save_all=True, append_images=resized[1:], loop=1, duration=50)I see following solutions here:
- Merge color palettes as well and reindex frames to new colors (hard one, losing an original data, might be impossible due to the limit of colors in the palette)
- First convert each frame from mode
P→RGBAand then make a merge (losing an original data) - Move merging to another level of abstraction allowing users to open GIF files exactly how there were composed (opening GIF would require additional actions)
So far I've made a workaround as follow (might be helpful for someone):
# Clear up the GifImageFile.load_end()
from PIL import Image, ImageFile
from PIL.GifImagePlugin import GifImageFile, _accept, _save, _save_all
class AnimatedGifImageFile(GifImageFile):
def load_end(self):
ImageFile.ImageFile.load_end(self)
Image.register_open(AnimatedGifImageFile.format, AnimatedGifImageFile, _accept)
Image.register_save(AnimatedGifImageFile.format, _save)
Image.register_save_all(AnimatedGifImageFile.format, _save_all)
Image.register_extension(AnimatedGifImageFile.format, ".gif")
Image.register_mime(AnimatedGifImageFile.format, "image/gif")
# Make merge by my own (losing an original palette
# doesn't matter for this particular case - having RGBA is good enough):
im = Image.open("src.gif")
last_frame = None
all_frames = []
try:
for i in range(0, 0xffffffff):
im.seek(i)
new_frame = im.convert('RGBA')
if last_frame is not None and im.disposal_method == 1:
updated = new_frame.crop(im.dispose_extent)
last_frame.paste(updated, im.dispose_extent, updated)
new_frame = last_frame
else:
last_frame = new_frame
# do resizing on new_frame here...
all_frames.append(new_frame)
except EOFError:
passReactions are currently unavailable
Metadata
Metadata
Assignees
Labels
BugAny unexpected behavior, until confirmed feature.Any unexpected behavior, until confirmed feature.GIF

