How to Make GIFs from Images Using FFmpeg
Contents
GIFs are fun—you can use them in emails, websites, blogs, and text messages to express emotions that cannot be expressed through words. Thanks to GIHPY, you can share and use GIFs on most social platforms like TikTok, Twitter, Facebook, and Instagram using the built-in search function within the apps.
You might have been using GIFs daily on these platforms but do you know you can use custom ones by uploading them to GIPHY? It has a built-in GIF maker that accepts image formats like PNG and JPG. However, you can only upload a single image and add animated text to it to create a GIF.
There’s no way to upload a batch of images if you want to turn candid moments captured using burst mode into GIFs. If you’re a developer, this could be something you can create to help people to turn their favorite moments into GIFs. In this tutorial, let’s learn how to make GIFs from images using FFmpeg.
What is FFmpeg
FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It can decode, encode, transcode, mux, demux, stream, filter and play any media file in any format. It is also highly portable as it compiles and runs in various build environments, machine architectures, and configurations like Linux, Mac OS X, Microsoft Windows, etc.
It contains multiple tools for end-users to convert, play and analyze media files and libraries for developers to use in different applications. In this tutorial, we will use the FFmpeg command-line tool.
Pre-requisite
You will need to download FFmpeg to make GIFs from images. For reference, the version of FFmpeg used in this tutorial is v5.0.1.
Basic Command
The simplest command takes all images in the current directory that match the specified filename pattern and creates an animated GIF using the default frame rate of 25fps (frames per second).
The filename pattern type is defined by the option -pattern_type
. By default, the pattern type used is sequence and it does not need to be specified explicitly in the command.
All you need in the command is the input filename pattern followed by the name of the output file.
ffmpeg -i image-%d.png output.gif
The command will read a sequence of files indexed by sequential numbers following the specified input filename pattern that may contain the string "%d" or "%0Nd".
From the command above, the filename pattern image-%d.png
contains "%d", which means it will read filenames in the format of ‘image-’ followed by index numbers 1, 2, 3, etc., and ends with ‘.png’.
For example, ‘image-1.png’, ‘image-2.png’, ‘image-3.png’, and so on.
In the GIF created, the order of the images will follow the index number in the filename.
If the format "%0Nd" is used, the sequential numbers have to be 0-padded and the number of digits is denoted by N. For example, if the input filename is changed to image-%03d.png
, it will read filenames ‘image-001.png’, ‘image-002.png’, ‘image-003.png’, etc.
🐻 Bear Tips : You can also specify the pattern type explicitly in the command by adding
-pattern_type sequence
.
Selecting a Range of Files
If you want to select only some of the images in the sequence, you can specify the starting index number using start_number
.
ffmpeg -start_number 5 -i image-%d.png output_2.gif
The command above will only select files with index number starting from 5 (image-5.png) and exclude other files before it like ‘image-1.png’, ‘image-2.png’, up to ‘image-4.png’.
Using a Wildcard to Select All Images in a Folder
If the images are not named following a pattern or format, you can select all images in the folder using a wildcard *
, given that the pattern type glob is used.
In the command, add -pattern_type glob
before the input:
ffmpeg -pattern_type glob -i '*.png' output_all.gif
When a wildcard is used in the filename followed by the file format, all files terminating with the specified extension suffix will be read. In this case, it means all filenames ending with “.png”, including “good.png” which does not follow the sequential filename format like other images in the folder.
However, unlike the default sequence pattern, you can’t determine the order of the images when you use a wildcard. It depends entirely on the glob pattern to determine the order in which the matched image files are processed.
Controlling the Transition Speed with Frame Rate
The default frame rate is 25fps, which means 25 frames will be shown within a second. It can be controlled by adding the framerate
option.
ffmpeg -framerate 1 -pattern_type glob -i '*.png' output_slow.gif
When the frame rate is set to 1, the next image will only be shown after one second. The lower the frame rate, the slower the transition speed, and vice versa.
Alternatively, you can use -r
which stands for “rate” to change the frame rate. It will generate the same result as using -framerate
.
ffmpeg -r 1 -pattern_type glob -i '*.png' output_slow.gif
As mentioned previously, the order of the images cannot be specified when you use the wildcard to select all images in a folder. From the GIF above, you can see that the images are not ordered as how they are named.
Fortunately, you can tackle this problem easily using Bannerbear.
Using Bannerbear API
Bannerbear is a tool that helps you generate custom images, videos, and more using API. As it offers a user-friendly drag-and-drop interface for designing the layout of an image, video, or GIF and allows you to modify the media files via API, performing media manipulation tasks becomes much easier as compared to using FFmpeg.
Using Bannerbear API, not only that the order of the images can be defined, but you can also control the duration of each image and apply a template like the one below to your GIFs.
In the GIF below, you can see that the images appear in the correct order. I have also set a longer duration for the last image so that the text on it can be read clearly.
As you can use the API via HTTP requests, SDKs (Ruby, Node.js, and PHP), or no-code integrations, it is very easy to create similar GIFs using other images based on the same template.
Here's an example of how the GIF can be made in Javscript using the Node.js library:
const gif = await bb.create_animated_gif('6jq8BX57ed9dbnlwWa', {
frame_durations: [0.04, 0.04, 1],
frames: [
[
{
name: 'frame', // first frame
image_url: 'https://ffmpeg-bb.s3.ap-southeast-1.amazonaws.com/Image+to+GIFs/image-1.png',
},
],
[
{
name: 'frame', // second frame
image_url: 'https://ffmpeg-bb.s3.ap-southeast-1.amazonaws.com/Image+to+GIFs/image-2.png',
},
],
[
{
name: 'frame', // third frame
image_url: 'https://ffmpeg-bb.s3.ap-southeast-1.amazonaws.com/Image+to+GIFs/image-3.png',
},
],
// you can add up to 30 frames
});
If you want to try adding this to your project, the API Reference has all information that you need. On top of that, you can find useful tutorials on our blog, like:
- How to Add Subtitles to a Video File Using FFmpeg
- How to Build a Video Thumbnail Generator Tool Using React and Bannerbear
- How to Start Generating Images Dynamically in PHP with Bannerbear
- How to Add Auto-Generated Custom Open Graph Images to WordPress Using Bannerbear
🐻 Bear Tips : Videos are also great materials for GIFs. Learn How to Make a GIF from a Video Using FFmpeg.
Conclusion
FFmpeg and Bannerbear are both very useful for handling media-related tasks. Depending on what you are creating, both serve different purposes. If you want to just simply create GIFs from images like what we are doing in this tutorial, using FFmpeg is good. Otherwise, using Bannerbear can save you a lot of time and trouble in adding other image manipulation functionalities like adding text, positioning elements, cropping images, etc.