AdvancedFee
AdvancedFee

Reputation: 3

How to remove white background of gif when using pillow?

I'm trying to display a gif on top of an image. The gif originally has a transparent background. The code below does that, except it created a black background around the original gif that flickers white when the gif resets. If I don't resize the gif then there would still be a white background around the original gif after its merged with the image.

Is there a way to keep the original gif's background transparent when merging?

from PIL import Image


background = Image.open('GrassyField.png').convert("RGBA")
gif = Image.open("1.gif")

foreground_w, foreground_w = gif.size
background_w, background_h = background.size
frames = []

for num in range(gif.n_frames):
    gif.seek(num)
    layer = Image.new('RGBA', (foreground_w, foreground_w), (0, 0, 0, 0)).resize((background_w, 
        background_h))
    layer.paste(background, (0, 0), mask=background)

    layer.paste(gif.resize((100, 100)).convert('RGBA'), (220, 25))

    frames.append(layer)
    frames[0].save('output.gif',
            save_all=True,
            append_images=frames[1:],
            duration=100,loop=0)

Upvotes: 0

Views: 896

Answers (1)

EvensF
EvensF

Reputation: 1610

Let's say that 1.gif is:

1.gif

and GrassyField.png is:

enter image description here

using this code:

import PIL.Image
import PIL.ImageSequence

with PIL.Image.open('1.gif') as foreground_animation, PIL.Image.open('GrassyField.png') as background_image:
    image_roles = {
        'foreground': foreground_animation, 
        'background': background_image.convert(mode='RGBA')
    }

    def create_frames(images_roles):
        for current_frame in PIL.ImageSequence.Iterator(image_roles['foreground']):
            current_background = image_roles['background'].copy()
            current_foreground = current_frame.convert(mode='RGBA').resize((100, 100))
            current_background.alpha_composite(current_foreground, dest=(220,25))
            yield current_background

    frames = tuple(create_frames(image_roles))
    frames[0].save(
        'output.gif',
        save_all=True,
        append_images=frames[1:],
        duration=100,loop=0
    )

You get output.gif:

enter image description here

Is that what you wanted?

Upvotes: 1

Related Questions