How to add GIF to a static background (Python + OpenCV). Video Generation series (Part 1)

A bad solution (with Pillow) and a good solution (with OpenCV).


  • Bad Solution
  • Good Solution
  • Plans for this series

Bad Solution

My original approach was making another gif. I had to expect it was a bad idea as I wanted to merge a colorful JPEG background and an animated GIF.

The source data – the background (left) and a GIF (right) to put on top of it.

So I used Pillow:

from PIL import Image, ImageSequence

background = 'data/background.jpg'
gif = 'data/intro.gif'
background ="RGBA")
animated_gif =
fps =['duration']

frames = []
for frame in ImageSequence.Iterator(animated_gif):
    frame = frame.convert("RGBA")

     clear_background = background.copy()
     clear_background.paste(frame, mask=frame)

frames[0].save('output.gif', save_all=True, append_images=frames)

And as a result I got this:

Generated GIF (background converted to RGBA)

It has decent FPS, but the number of colors is too low. It is typical and was to be expected.

However, if I change line 3 to:

    background = # .convert("RGBA")

Then the overall result changes, but it still corrupts the background:

Generated GIF (background NOT converted to RGBA)

See the difference between the original, RGBA and non-RGBA:

Original background and two (RGBA and non-RGBA) GIFs comparisons

And of course they all are heavy af – all GIFs are.

Good Solution

I was too involved in the process of making the PIL script work I got carried away and spent too much time of what looked like a vain idea.

Let’s get back to our beloved OpenCV and try and find a solution for it.

First of all, we need to make a video that consists of just the background image:

import cv2

background_image = 'data/background.jpg'
gif_image = 'data/intro.gif'

# load the background picture nad get width/height
background = cv2.imread(background_image)
background = background.astype(float)
height, width, color = background.shape

# set up the final video with 25 fps
video_destination = 'clips/intro.avi'
video = cv2.VideoWriter(video_destination, 0, 25, (width, height))

# open GIF
gifcap = cv2.VideoCapture(gif_image)

# iterated GIF frames and add it to the background while the GIF lasts
while gifcap.isOpened():
    ret, frame =

    if ret:
        output = frame.copy()
        foreground = output.astype(float)
        output = cv2.add(foreground, background).astype(np.uint8)
    else: break

# close the GIF
# close the resulting video

This became easy once I found the cv2.add(foreground, background) method.

As a result I got a perfectly good video. The result you see below is a GIF I generated from the video I got (as WordPress does not let me upload a video unless I pay them $100 – tough luck). The quality is not ideal.

Plans for this series

The next posts in the series will be about

  1. Making a small GIF out of a big video (like the result you see above).
  2. Resizing videos
  3. Adding a GIF on the foreground of a video (or GIF) background.
  4. Lowering the size of videos with python-ffmpeg.

3 thoughts on “How to add GIF to a static background (Python + OpenCV). Video Generation series (Part 1)

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.