Create Video from Mixed Resolution Images in FFmpeg

This guide explains how to convert a directory of images with varying dimensions and aspect ratios into a single, standardized video using FFmpeg. When stitching together images of different sizes, FFmpeg requires each frame to be scaled and padded to a uniform resolution to prevent rendering errors. Below are the precise commands and filter configurations needed to normalize, scale, and compile your images into an MP4 video.

1. The Scaling and Padding Strategy

To combine images of different dimensions without distorting their aspect ratios, you must scale each image to fit within a target canvas (such as 1920x1080) and pad the remaining empty space with black bars (letterboxing or pillarboxing).

This is achieved using the scale and pad video filters:

  • scale=1920:1080:force_original_aspect_ratio=decrease: Scales the image to fit entirely within the 1920x1080 boundary while preserving the original aspect ratio.
  • pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black: Places the scaled image into the center of a black 1920x1080 canvas.
  • setsar=1: Sets the sample aspect ratio to 1:1 to prevent pixel distortion during playback.

2. Method A: Using Glob Pattern (Linux and macOS)

If your images are randomly named or you are working in a Unix-based environment, use the -pattern_type glob input option.

ffmpeg -framerate 1 -pattern_type glob -i '*.jpg' \
  -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1" \
  -c:v libx264 -r 30 -pix_fmt yuv420p output.mp4

3. Method B: Using a Concat Demuxer (Universal / Windows)

The glob pattern does not work natively on Windows command prompt. The most reliable cross-platform method is using a text file list.

  1. Generate a text file named input.txt listing each image and duration:
file 'image1.png'
duration 2
file 'image2.jpg'
duration 2
file 'image3.jpeg'
duration 2
file 'image3.jpeg'

(Note: The last file must be repeated without a duration to ensure the final frame is rendered properly).

  1. Run the FFmpeg command:
ffmpeg -f concat -safe 0 -i input.txt \
  -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1" \
  -c:v libx264 -r 30 -pix_fmt yuv420p output.mp4

4. Alternative: Crop to Fill (Avoid Black Bars)

If you prefer the video frame to be completely filled without black bars, scale the image up to cover the canvas and crop the excess edges:

ffmpeg -framerate 1 -pattern_type glob -i '*.jpg' \
  -vf "scale=1920:1080:force_original_aspect_ratio=increase,crop=1920:1080,setsar=1" \
  -c:v libx264 -r 30 -pix_fmt yuv420p output.mp4

Parameter Breakdown

  • -framerate 1: Dictates the input speed (1 frame per second, meaning each image shows for 1 second).
  • -r 30: Sets the output frame rate to 30 fps for smooth playback compatibility across media players.
  • -c:v libx264: Encodes using the H.264 video codec.
  • -pix_fmt yuv420p: Sets the pixel format to YUV 4:2:0, ensuring broad hardware and browser compatibility.