Modify all frames in a GIF - split into frames, process each frame, and create a new GIF

Viewed 249

I've been experimenting with PIL/Pillow and I've hit a brick wall. I've been trying to take a GIF, split it up into frames, modify the colour depth for each frame, and then join the frames up into a GIF again.

Here is my code:

from PIL import Image

def gif_depth_change(pathToGIF, colourDepth):
    originalGIF = Image.open(pathToGIF)
    newGIF = originalGIF.convert("P", palette=Image.ADAPTIVE, colors=colourDepth)
    newGIF.show()

The convert() method doesn't seem to work here, as it only shows a single PNG that doesn't have the colour depth given as an argument.

I also tried this:

def gif_depth_change(pathToGIF, colourDepth):
    originalGIF = Image.open(pathToGIF)
    newFrames = []
    for frame in range(0, originalGIF.n_frames):
        originalGIF.seek(frame)
        x = originalGIF.convert("P", palette=Image.ADAPTIVE, colors=colourDepth)
        newFrames.append(x)
    newFrames[0].save('changed-depth-gif.gif', format='GIF', append_images=newFrames[1:], save_all=True)

When run, this code saves a GIF but doesn't modify it in any way (it gives me the same GIF). I also tried using convert() on originalGIF.seek(frame) but that returned None.

1 Answers

Like this:

from PIL import Image


def process_image(filename, color_depth):
    original = Image.open(filename)

    new = []
    for frame_num in range(original.n_frames):
        original.seek(frame_num)
        new_frame = Image.new('RGBA', original.size)
        new_frame.paste(original)
        new_frame = new_frame.convert(mode='P', palette=Image.ADAPTIVE, colors=color_depth)
        new.append(new_frame)

    new[0].save('new.gif', append_images=new[1:], save_all=True)


if __name__ == '__main__':
    process_image('test.gif', 4)

It loops through each frame of the original and creates a copy, which it then converts and adds to the list of new frames. These are then saved together as a single gif.

Related