2

I am trying to resize an animated GIF. Original image here. I am doing this by loading each frame separately, saving it as one picture, and then resizing this picture with PIL.Image.resize() and saving it in a list, then appending the entire list to the saved GIF (total 60 frames). When looking through the individually saved frames, there is no problem. But when I look at the saved resized animated GIF, there is significant quality loss: Resized image here. I don't know if this is caused by the saving algorithm of PIL or what, I just need to save this GIF in the original quality, not grainy like this. I tested multiple sizes, including the original size (= thus avoiding the resizing part), but it seems to happen every time.

def get_frames(path=''):
    import Image
    from tkinter import PhotoImage

    source_image = Image.open(path)
    i = 0
    palette = source_image.getpalette()

    frames = []
    try:
        while 1:
            source_image.putpalette(palette)
            frames.append(Image.new("RGBA", source_image.size))
            frames[i].paste(source_image)

            i += 1
            source_image.seek(i)
    except EOFError:
        pass
    out = []
    for frame_index in range(len(frames)):
        frames[frame_index].save('../temp/frame{}.gif'.format(frame_index))
        out.append('../temp/frame{}.gif'.format(frame_index))
    return out
# This part creates 60 files (each for one frame),
# then returns the list of paths to those files

def downsize_frame(image_path='', new_width=30, new_height=30):
    from PIL import Image
    img = Image.open(image_path)
    img = img.resize((new_width, new_height), Image.ANTIALIAS)
    return img
# This returns the smaller image

frames = []
image = 'example.gif'
source = get_frames(path=image)
for loop in range(1, max_index):
    from tkinter import TclError
    try:
        frames.append(downsize_frame(image_path=source[loop], new_width=48, new_height=48))
    except IndexError:
        frames.append(new_image)
new_image.save(out_name, 'gif', transparency=0, duration=100, loop=0,
               append_images=frames, save_all=True, version='GIF89a')
Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
Arm3tt
  • 21
  • 5
  • Kindly share your code so we can see what you are doing and try to assist you better. – Mark Setchell Apr 12 '20 at 11:16
  • 1
    @MarkSetchell Sure, sorry if it's a bit hard to understand, again, I think the problem is somewhere at the `new_image.save()`, as the frames alone aren't affected. – Arm3tt Apr 12 '20 at 11:29
  • 1
    When you use `resize()` with `Filter.ANTIALIAS` you introduce new colours into the limited palette. Maybe try with `Filter.NEAREST` so you only use colours present in the original palette. – Mark Setchell Apr 12 '20 at 11:44
  • There is no need to edit in "Thanks" or the link to the duplicate (it's already shown at the top). – Gino Mempin Apr 17 '20 at 04:49
  • 2
    I experienced the same issue (with any transformation - not just resizing) and instead of doing `new_images.save(out_name, duration=100, append_images=frames)` I used [imageio](https://stackoverflow.com/a/35943809) as `imageio.mimsave(out_name, frames, duration=0.1)`. This resolved my issues. – CNugteren Apr 23 '21 at 07:34

0 Answers0