Discoloration in GIF saved by imageio

388 Views Asked by At

I have a list of PIL images I want to turn into a GIF. I have a gray mouse moving around in a maze, following a cyan dot. However, the mouse renders as cyan in the saved GIF, and I don't know why.

Here's a link to the GIF (in mp4 format). Here's a link to what the mouse should look like.

Here's the code I used to generate the GIF:

import PIL

imgs = []
fig, ax = plt.subplots(1, 1, figsize=(4, 4))

# np_grids is a list of grids I used to render the maze frames; these details seem unimportant
for idx, grid in enumerate(np_grids): 
    # [Code which plots something interesting on ax]
    
    # Get the axis as an image
    fig.tight_layout()
    fig.canvas.draw()
    img = PIL.Image.frombytes('RGB', fig.canvas.get_width_height(),fig.canvas.tostring_rgb())
    imgs.append(img)

target_file = 'example.gif'

start_step = 25 # Start the gif at this step

# Save the gif
imgs[start_step].save(target, format="GIF", save_all=True, append_images=imgs[start_step+1:], duration=100, loop=0)

imgs appears to contain the correct images, as plotting with plt.imshow(imgs[0]) gives the desired result.

I've tried saving via a few different tools, using both imageio and the save function in the PIL.Image class. I hoped one would use a different algorithm to save the GIF and therefore have better coloration, but both approaches produced similar results.

EDIT: I solved the problem thanks to the comments. I changed the img generation code to:

    img = PIL.Image.frombytes('RGB', fig.canvas.get_width_height(),fig.canvas.tostring_rgb())
    if idx == 0: # Quantize the first frame and get the palette
        img = img.quantize(colors=254, method=PIL.Image.Quantize.MAXCOVERAGE)
    else: # Quantize all other frames to the same palette
        img = img.quantize(colors=254, palette=imgs[0], method=PIL.Image.Quantize.MAXCOVERAGE)
    imgs.append(img)
0

There are 0 best solutions below