How to Use FFmpeg Zoompan Filter for Camera Movement

This article explains how to use the FFmpeg zoompan filter to create dynamic camera movements, such as panning, zooming, and tilting, over high-resolution still images or canvases. You will learn the core syntax of the filter, how to calculate coordinates to prevent pixelation, and how to apply practical configurations to generate smooth, high-quality video outputs.

Understanding the Zoompan Filter

The zoompan filter works by cropping a specific portion of an input image and scaling it to the target output size for each frame. By changing the crop area (x and y coordinates) and the zoom level (z) frame-by-frame, you simulate camera movement.

The filter uses several key variables: * zoom (or z): The zoom factor (e.g., 1.5 means 150% zoom). * x: The horizontal coordinate of the top-left corner of the crop box. * y: The vertical coordinate of the top-left corner of the crop box. * d: The duration of the effect in frames (default is 90). * s: The output resolution (default is 1280x720). * iw / ih: Input width and input height.


The Golden Rule for High-Resolution Canvases

By default, FFmpeg’s zoompan filter downscales the input image to 1280x720 before applying the zoom. This results in heavy pixelation when zooming in on a high-resolution canvas.

To preserve high quality, you must explicitly set the output size using the s parameter (e.g., s=1920x1080 for Full HD or s=3840x2160 for 4K) to match your desired output resolution.


Practical Examples of Camera Movements

1. Smooth Zoom-In to the Center

To zoom into the center of a high-resolution image, you must continuously recalculate the x and y coordinates to keep the crop box centered as the zoom factor (z) increases.

ffmpeg -loop 1 -i input.jpg -vf "zoompan=z='min(zoom+0.0015,1.5)':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':d=150:s=1920x1080" -c:v libx264 -t 5 -pix_fmt yuv420p output.mp4

2. Slow Left-to-Right Pan (Ken Burns Effect)

To create a panning effect, keep the zoom level constant and move the horizontal coordinate x over time using the current frame number (on).

ffmpeg -loop 1 -i input.jpg -vf "zoompan=z=1.5:x='(iw-iw/zoom)*(on/150)':y='(ih-ih/zoom)/2':d=150:s=1920x1080" -c:v libx264 -t 5 -pix_fmt yuv420p output.mp4

3. Diagonal Pan and Zoom (Tilt-Zoom)

To zoom in while simultaneously moving the camera diagonally from the top-left to the bottom-right:

ffmpeg -loop 1 -i input.jpg -vf "zoompan=z='min(zoom+0.002,1.3)':x='(iw-iw/zoom)*(on/150)':y='(ih-ih/zoom)*(on/150)':d=150:s=1920x1080" -c:v libx264 -t 5 -pix_fmt yuv420p output.mp4

How to Prevent Jitter and Stuttering

FFmpeg’s coordinate system for cropping operates on integers. If your math results in fractional numbers, FFmpeg truncates them, which often causes a micro-stutter or “jitter” effect.

To achieve perfectly smooth motion: 1. Match the Framerate: Force a consistent input and output framerate using the fps filter before the zoompan filter. 2. Add a Scale Filter: If your input image is exceptionally large (e.g., 8000x6000), scale it down slightly to a manageable high-resolution canvas (like 3840x2160) before applying zoompan.

Here is an optimized command for ultra-smooth rendering:

ffmpeg -loop 1 -i input.jpg -vf "scale=3840:2160,fps=60,zoompan=z='min(zoom+0.001,1.3)':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':d=300:s=1920x1080,fps=60" -c:v libx264 -t 5 -pix_fmt yuv420p output.mp4