Skip to content

Instantly share code, notes, and snippets.

@karbassi
Created May 1, 2023 15:04
Show Gist options
  • Save karbassi/837a8439ec960ca26067f4940a099ddc to your computer and use it in GitHub Desktop.
Save karbassi/837a8439ec960ca26067f4940a099ddc to your computer and use it in GitHub Desktop.
Create Animated GIFs from Images with FFmpeg Using a Bash Script

Creating a GIF from a series of images is a simple process with the right tools. This bash script simplifies the process using FFmpeg, a popular multimedia tool for handling multimedia data.

How to use the script

Here's how to use the script:

./create-gif.sh <path-to-images> [pattern] [output] [fps]
  • path-to-images (required): The path to the folder containing the images you want to convert into a GIF.
  • pattern (optional): The pattern to use to find the images. By default, the script uses '%d.png'.
  • output (optional): The output file name. By default, the script uses the folder name + .gif.
  • fps (optional): The frames per second (FPS) for the output. By default, the script uses 10 FPS.

Examples

Here are some examples to help you get started:

Example 1: Convert all images in a folder to a GIF

./create-gif.sh /path/to/images

This command converts all the images in the '/path/to/images' folder to a GIF with a default name, which is the folder name + '.gif', and default FPS, which is 10 FPS.

Example 2: Convert images in a folder with a pattern to a GIF

./create-gif.sh /path/to/images 'image-%d.png'

This command converts all the images in the '/path/to/images' folder that follow the 'image-%d.png' pattern to a GIF with a default name and default FPS.

Example 3: Convert images in a folder with a pattern to a specified output file

./create-gif.sh /path/to/images 'image-%d.png' output.gif

This command converts all the images in the '/path/to/images' folder that follow the 'image-%d.png' pattern to a GIF with a specified output file name, 'output.gif', and default FPS.

Example 4: Convert images in a folder with a pattern to a specified output file with a specified FPS

./create-gif.sh /path/to/images 'image-%d.png' output.gif 15

This command converts all the images in the '/path/to/images' folder that follow the 'image-%d.png' pattern to a GIF with a specified output file name, 'output.gif', and specified FPS of 15.

How the script works

The script starts by checking if the input is a folder, and if not, it displays an error message and exits. Next, it sets the pattern and output filenames based on the arguments or default values. It then creates a color palette for the GIF using the palettegen filter in FFmpeg. The palettegen filter creates a color palette that contains all the colors used in the images.

After creating the palette, the script uses the paletteuse filter to map the image colors to the palette colors. The paletteuse filter applies the color palette to the input images and creates the final GIF. Finally, the script removes the palette file to clean up.

One thing to note is that the palettegen filter generates a palette file that is used by the paletteuse filter. The script stores this file in the input folder with the name 'palette.png'. If you run the script multiple times in the same folder, it will overwrite the existing palette file. It is essential to keep this in mind when using the script.

#!/usr/bin/env bash
# Create a gif using ffmpeg from a series of images.
# Usage: create-gif.sh <path-to-images> [output] [fps]
help() {
echo "Usage: create-gif.sh <path-to-images> [pattern] [output] [fps]"
echo ""
echo "Examples: "
echo " ${0} ./images"
echo " ${0} ./images 'file-%d.png'"
echo " ${0} ./images 'file-%d.png' ./output.gif"
echo " ${0} ./images 'file-%d.png' ./output.gif 10"
echo ""
echo "Options: "
echo " path-to-images: Path to the folder containing the images"
echo " pattern: Pattern to use to find the images, default to '%d.png'"
echo " output: Output file, default to folder name + .gif"
echo " fps: Frames per second, default to 10"
echo ""
}
# Input folder
INPUT_FOLDER=$1
# Check if input is a folder
if [ ! -d "$INPUT_FOLDER" ]; then
echo "Error: $INPUT_FOLDER is not a folder"
echo ""
help
exit 1
fi
# Pattern is optional, default to "folder_name/folder-name-%d.png"
INPUT_FOLDER_NAME=$(basename "$INPUT_FOLDER")
PATTERN=${2:-"$INPUT_FOLDER_NAME-%d.png"}
# Input files
INPUT="$INPUT_FOLDER_NAME/$PATTERN"
# Output is optional, default to "folder_name/folder_name.gif"
OUTPUT=${3:-"$INPUT_FOLDER_NAME/$INPUT_FOLDER_NAME.gif"}
# FPS is optional, default to 10
FPS=${3:-10}
# # echo for debugging
# echo "Input: $INPUT"
# echo "Pattern: $PATTERN"
# echo "Output: $OUTPUT"
# echo "FPS: $FPS"
# echo ""
# Create a palette for the gif
ffmpeg \
-loglevel error \
-hide_banner \
-nostats \
-y \
-i "$INPUT" \
-vf palettegen \
"$INPUT_FOLDER_NAME/palette.png"
# Run the script with no output unless there is an error
ffmpeg \
-loglevel warning \
-hide_banner \
-nostats \
-y \
-framerate "$FPS" \
-i "$INPUT" \
-i "$INPUT_FOLDER_NAME/palette.png" \
-filter_complex "paletteuse" \
"$OUTPUT"
# Remove the palette
rm "$INPUT_FOLDER_NAME/palette.png"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment