Creating movies and GIFs from a series of photos

I sometimes use ‘burst mode’ on my camera if I’m making photographs of my daughter (or cat), so I can select the best photo and discard the rest. After a while I found out that these burst-photos are also cool to show as a video. These short ‘movies’ look they are shot with an old-fashioned videocamera.

Here’s my process 🤓

Images to MP4

The command to create a movie from a series of jpg-images (without resizing):

ffmpeg -r 10 -pattern_type glob -i "*.JPG" -vcodec libx265 -tag:v hvc1 -preset veryslow -crf 20 -an -pix_fmt yuv420p result.mp4

CRF is a factor to indicate quality/filesize. I find it extremly hard to judge the result from this. One source suggests using CRF 16, but to my eye there is no difference between 17 or 20. You can check for yourself with two samples I generated: image 1, image 2. I’ve included the previous encoder of choice in the table below as well to show how impressive H.265 is. According to the documentation, CRF 23 is default in H.264 and CRF 28 is default in H.265.

Setting Filesize Quality
H.264, CRF 17 38MB great
H.265, CRF 17 27,5MB great
H.265, CRF 20 17,2MB great
H.264, CRF 23 13,7MB good
H.265, CRF 28 3,5MB good (impressive for this filesize)

for 24 JPG images all at 4,7MB (totaling 112,8MB)

Images to GIF

H.265 is nice, but sometimes you need a more archaic format if you want to share your movie. The following incantation converts a series of images to a GIF. You will need ffmpeg and ImageMagick installed (which is easy, if you have brew on your Mac).

ffmpeg -pattern_type glob -i "*.jpg" -vf scale=800:-1 -r 10 -f image2pipe -vcodec ppm - | convert -delay 10 -layers Optimize -loop 0 - result.gif

The above seems to create the best looking gif for the smallest filesize (2,5MB for the same 24 images).

Other methods I’ve tried:

Different dithering (looks good, bigger filesize)

ffmpeg -r 10 -pattern_type glob -i "*.JPG" -vf scale=800:-1:sws_dither=ed -an -pix_fmt rgb8 ffmpeg_dither.gif

Using palette creation and different rescaling (not a great result, also big file)

ffmpeg -r 10 -pattern_type glob -i "*.JPG" -vf scale=800:-1:flags=lanczos,palettegen -an -pix_fmt rgb8 -y tmp_palette.png
ffmpeg -r 10 -pattern_type glob -i "*.JPG" -i tmp_palette.png -lavfi scale=800:-1:flags=lanczos,paletteuse=dither=floyd_steinberg -an -pix_fmt rgb8 -y ffmpeg_lanczos_palette_dither.gif

Here’s more info on these settings

note: ImageMagick uses ‘delay’ and FFMPeg uses FPS. The delay in ImageMagick is described in ticks (1/100 of a second). So 20 FPS is a delay of 5 (delay=100/FPS)

Optimization

Apparently ImageMagick already does a great job of optimizing. Using gifsicle --optimize does not result in a smaller filesize (sometimes even enlarging the file).

Tools used: ffmpeg 3.4.1, imagemagick 7.0.7-18