Add Zoom Effects To Images With MoviePy

In this article, I want to share a technique that can be used to add zoom effects to your photos. You also don’t need to install any software for this, these zoom effects can be created entirely in Python.

I will show you how to create both zoom-in and zoom-out effects on images and save them as videos. You can use these effects to automate video creation for social media as well.

I’ll be using the following image for this task.

python zoom-in effect

However, you can use any image with the same Python code.

So, to get started, first import the required Python modules.

from PIL import Image
import numpy as np
import moviepy.editor as mp
import math

Add zoom-in effect to an image

Specify the image path and the desired image dimensions (size). The output video will have the same dimensions.

image_path = 'input_image.png'
image_size = (340, 512)

Below is the main function to perform a zoom-in effect on the input image.

def zoom_in_effect(clip, zoom_ratio=0.04):
    def effect(get_frame, t):
        img = Image.fromarray(get_frame(t))
        base_size = img.size

        new_size = [
            math.ceil(img.size[0] * (1 + (zoom_ratio * t))),
            math.ceil(img.size[1] * (1 + (zoom_ratio * t)))
        ]

        # The new dimensions must be even.
        new_size[0] = new_size[0] + (new_size[0] % 2)
        new_size[1] = new_size[1] + (new_size[1] % 2)

        img = img.resize(new_size, Image.LANCZOS)

        x = math.ceil((new_size[0] - base_size[0]) / 2)
        y = math.ceil((new_size[1] - base_size[1]) / 2)

        img = img.crop([
            x, y, new_size[0] - x, new_size[1] - y
        ]).resize(base_size, Image.LANCZOS)

        result = np.array(img)
        img.close()

        return result

    return clip.fl(effect)

I have taken this piece of code from gist.github.com/mowshon/2a0664fab0ae799734594a5e91e518d5

Next, I will specify a few parameters for the output video that will determine the duration, speed of zoom-in effect, and smoothness of the video.

# specify parameters for the zoom-in effect
zoom_factor = 0.06
duration = 7  # seconds
fps = 40 

Finally, I will pass the input image as an ImageClip object to the zoom_in_effect() function. The output video will get saved to the same working directory.

slides = mp.ImageClip(image_path).set_fps(fps).set_duration(duration).resize(image_size)

# add zoom-in effect to input image
video = zoom_in_effect(slides, zoom_factor)

# save video
video.write_videofile('zoomin.mp4')

Add zoom-out effect to an image

I have tweaked the zoom-in effect function a little bit to perform zoom-out animation using the same input image.

def zoom_out_effect(clip, zoom_max_ratio=0.2, zoom_out_factor=0.04):
    def effect(get_frame, t):
        img = Image.fromarray(get_frame(t))
        base_size = img.size

        # Reverse the zoom effect by starting zoomed in and zooming out
        scale_factor = zoom_max_ratio - (zoom_out_factor * t)
        scale_factor = max(scale_factor, 0)  # Ensure scale factor doesn't go negative

        new_size = [
            math.ceil(base_size[0] * (1 + scale_factor)),
            math.ceil(base_size[1] * (1 + scale_factor))
        ]

        # The new dimensions must be even.
        new_size[0] = new_size[0] - (new_size[0] % 2)
        new_size[1] = new_size[1] - (new_size[1] % 2)

        img = img.resize(new_size, Image.LANCZOS)

        x = math.ceil((new_size[0] - base_size[0]) / 2)
        y = math.ceil((new_size[1] - base_size[1]) / 2)

        img = img.crop([
            x, y, new_size[0] - x, new_size[1] - y
        ])

        # Resize back to base size
        img = img.resize(base_size, Image.LANCZOS)

        result = np.array(img)
        img.close()

        return result

    return clip.fl(effect)

# specify parameters for the zoom-out effect
zoom_max_ratio = 0.3 # Maximum zoom-in at the start
zoom_out_factor = 0.04  # Zoom-out speed
duration = 6  # Duration of the video
fps = 40  # Frames per second

slides2 = mp.ImageClip(image_path).set_fps(fps).set_duration(duration).resize(image_size)

video2 = zoom_out_effect(slides2, zoom_max_ratio, zoom_out_factor)

video2.write_videofile('zoomout.mp4')

Leave a Reply

Your email address will not be published. Required fields are marked *