FFmpeg Zoompan: Camera Movement on High-Res Canvas
This article explains how to use FFmpeg's zoompan filter
to execute smooth panning and zooming across a high-resolution canvas
without losing image quality. You will learn how the filter operates,
how to bypass its default downscaling behavior, and how to construct
commands for linear pans, gradual zooms, and combined cinematic camera
paths.
The Default Resolution Pitfall
By default, the zoompan filter sets its working viewport
and output resolution to 1280x720. If you input an
ultra-high-resolution image (such as 4K, 8K, or a wide panorama), FFmpeg
will downscale the entire canvas to 720p before cropping and zooming,
resulting in blurry, pixelated footage.
To maintain full canvas fidelity, you must explicitly define the
output size using the s parameter or process the frame
dimensions dynamically within the filter.
Key Zoompan Parameters
The zoompan filter relies on several key variables and
options:
z: The zoom factor. Evaluated each frame.z=1displays the base crop window;z=2zooms in by 2x.xandy: The top-left coordinates of the crop area on the source canvas.d: Duration of the effect in total output frames.s: Output video resolution (e.g.,1920x1080).fps: Frame rate of the generated video (defaults to 25).on: The current output frame count, starting from 0.
Example 1: Horizontal Pan Across a Wide Image
To move the camera smoothly from the left side of a high-resolution
image to the right without zooming, set a fixed zoom level and increment
the x coordinate on every frame.
ffmpeg -loop 1 -i input.jpg -vf "zoompan=z=1:x='on*(iw-ow)/300':y='(ih-oh)/2':d=300:s=1920x1080:fps=30" -t 10 -c:v libx264 -pix_fmt yuv420p pan_horizontal.mp4d=300andfps=30produce a 10-second sequence (300 frames / 30 fps).x='on*(iw-ow)/300'slides the crop window from frame0(x = 0) to frame300(x = input width minus output width).y='(ih-oh)/2'centers the camera vertically.
Example 2: Smooth Zoom-In on a High-Resolution Canvas
To zoom into a specific point on the canvas, increment z
on each frame while updating x and y to keep
the target centered.
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=300:s=1920x1080:fps=30" -t 10 -c:v libx264 -pix_fmt yuv420p zoom_center.mp4z='min(zoom+0.0015,1.5)'gradually increases the zoom factor from 1.0 to 1.5.x='(iw/2)-(iw/zoom/2)'andy='(ih/2)-(ih/zoom/2)'ensure the zoom centers on the middle of the source canvas by recalculating the visible window relative to the current zoom level.
Example 3: Diagonal Pan with Simultaneous Zoom
To move diagonally while zooming in toward an off-center region:
ffmpeg -loop 1 -i input.jpg -vf "zoompan=z='min(zoom+0.002,1.8)':x='on*2':y='on*1.5':d=300:s=1920x1080:fps=30" -t 10 -c:v libx264 -pix_fmt yuv420p pan_and_zoom.mp4x='on*2'shifts the viewport 2 pixels rightward per frame.y='on*1.5'shifts the viewport 1.5 pixels downward per frame.- Ensure that
x + (iw/zoom)andy + (ih/zoom)do not exceed the original image boundaries (iwandih), otherwise the filter will clamp or distort the edge of the frame.
Best Practices for Smooth Output
- Coordinate Rounding: If you observe jitter during
slow movements, it is often due to pixel rounding in the integer crop
coordinates. Upscaling the source image using the
scalefilter prior tozoompanprovides finer sub-pixel movement steps before the final frame is rendered. - Pixel Format: Always append
-pix_fmt yuv420pwhen encoding withlibx264to ensure the generated MP4 file is compatible with web browsers and standard media players.