Le tutoriel ultime pour créer ses propres GIF sous GNU/Linux

Intro

Il y a énormément de GIF disponibles gratuitement sur internet mais il n'est pas rare de ne pas trouver celui que l'on cherche ou dans des qualités médiocres. Voici donc un guide complet que j'utilise personnelement pour créer mes propres GIF sur GNU/Linux.

Installation des outils

root@host:~# apt install imagemagick ffmpeg

Créer son GIF depuis une vidéo

Convertir la séquence vidéo en fichiers png

La première chose à faire est de convertir une séquence vidéo en plusieurs fichiers images. Ici nous capturons la séquence vidéo de 2m16s à 2m22s.

user@host:~$ ffmpeg -ss 2:14 -t 6 -i /movies/1988.Rambo.III.MULTI.x264.1080p.mkv -vf fps=10,scale=320:-1 $filename%05d.png

Suppression des images inutiles

Ensuite nous supprimons les images que l'on ne souhaite pas inclure dans notre GIF.

Remove unwanted frames

Conversion des fichiers images vers un fichier GIF

user@host:~$ convert -loop 0 *.png myimage.gif

Résultat

Sylvester Stallone dans Rambo III qui met son bandeau rouge

Suppression des bandes noires

Dans certains films des bandes noires en haut et en bas de l'image peuvent être présentes. Voici comment les supprimer.

Convertir la séquence vidéo en fichiers png

user@host:~$ ffmpeg -ss 8:26 -t 9 -i /movies/2000.American.Psycho.MULTI.AC3.1080p.x264.mkv -vf fps=10,scale=320:-1 $filename%05d.png

Suppression des bandes noires

user@host:~$ identify 00039.png
00039.png PNG 320x180 320x180+0+0 8-bit sRGB 79528B 0.000u 0:00.000

Nous allons passer de 180 à 130 pixels en hauteur (180-25-25=130) :

user@host:~$ convert -crop 320x130+0+25 00039.png +repage Cropped_00039.png
user@host:~$ for i in 000*; do convert -crop 320x130+0+25 "$i" +repage Cropped_"$i"; done

Conversion des fichiers images vers un fichier GIF

user@host:~$ convert -loop 0 Cropped*.png myimage.gif

Résultat

Christian Bale dans American Psycho en train de rigoler

Ajouter du texte à notre GIF

Convertir la séquence vidéo en fichiers png

user@host:~$ ffmpeg -ss 19:24 -t 5 -i /movies/1998.The.Big.Lebowski.MULTI.1080p.Bluray.x264.mkv -vf fps=10,scale=320:-1 $filename%05d.png

Ajouter du texte à une image

user@host:~$ convert 00016.png -font Cantarell-Extra-Bold -gravity south -pointsize 30 -stroke black -fill white -strokewidth 1 -annotate +0+0 'YOU'\''RE\nAN ASSHOLE!!!' Text_00016.png
Jeff Bridges dans The Big Lebowski, t'es un sale con!

Ajouter du texte à plusieurs images

user@host:~$ for i in 000*; do cp "$i" Text_"$i"; done
user@host:~$ for i in 0001[6-9]*; do convert "$i" -font Cantarell-Extra-Bold -gravity south -pointsize 30 -stroke black -fill white -strokewidth 1 -annotate +0+0 'YOU'\''RE\nAN ASSHOLE!!!' Text_"$i"; done
user@host:~$ for i in 0002[0-7]*; do convert "$i" -font Cantarell-Extra-Bold -gravity south -pointsize 30 -stroke black -fill white -strokewidth 1 -annotate +0+0 'YOU'\''RE\nAN ASSHOLE!!!' Text_"$i"; done

Conversion des fichiers images vers un fichier GIF

user@host:~$ convert -loop 0 Text_*.png myimage.gif

Résultat

Jeff Bridges dans le film The Big Lebowski, t'es un sale con!

Police Impact

Si l'on souhaite ajouter du texte avec la police habituelle des GIF on va avoir besoin de copier la police impact depuis un poste Windows vers notre station GNU/Linux.

Windows Fonts Directory Impact
root@host:~# mkdir /usr/share/fonts/WindowsFonts
root@host:~# mv impact.ttf /usr/share/fonts/WindowsFonts/
user@host:~$ fc-cache --force
user@host:~$ ffmpeg -ss 10:48 -t 2 -i /movies/1997.Batman.and.Robin.MULTi.1080p.AC3.mkv -vf fps=10,scale=320:-1 $filename%05d.png
user@host:~$ for i in 000*; do cp "$i" Text_"$i"; done
user@host:~$ for i in 0000[2-7]*; do convert "$i" -font Impact -gravity south -pointsize "55" -stroke black -fill white -strokewidth 1 -annotate +0+0 'FREEZE...'  Text_"$i"; done
user@host:~$ for i in 0001[0-4]*; do convert "$i" -font Impact -gravity south -pointsize "55" -stroke black -fill white -strokewidth 1 -annotate +0+0 'T'\''ES GIVRÉ!'  Text_"$i"; done
user@host:~$ convert -loop 0 Text_000* myimage.gif

Résultat

Batman : Freeze, t'es givré!

Jouer avec le texte

Défilement d'un texte

On peut aussi simuler un défilement de texte.

Convertir la séquence vidéo en fichiers png

user@host:~$ ffmpeg -ss 16:43 -t 1 -i /movies/1993.groundhog.day.MULTI.1080p.bluray.x264.mkv -vf fps=10,scale=320:-1 $filename%05d.png

Ajout du texte

user@host:~$ a=-250;for i in 000*; do convert "$i" -font Cantarell-Extra-Bold -gravity south -pointsize 35 -stroke black -fill white -strokewidth 1 -annotate -"$a"+0 'I'\''M THINKING...' Texted_${i}; ((a+=60)); echo "$a"; done
a=-250
for i in 000*
do 
	convert "$i" -font Cantarell-Extra-Bold -gravity south -pointsize 35 -stroke black -fill white -strokewidth 1 -annotate -"$a"+0 'I'\''M THINKING...' Texted_${i}
	a=$((a+60))
	echo "$a"
done

Conversion des fichiers images vers un fichier GIF

user@host:~$ convert -loop 0 Texted_*.png myimage.gif

Résultat

Bill Murray dans le film Un jour sans fin, je réfléchis

Texte qui tremble

On peut simuler un tremblement du texte

Convertir la séquence vidéo en fichiers png

user@host:~$ ffmpeg -ss 45:02 -t 2 -i /movies/1995.ace.ventura.when.nature.calls.MULTI.1080p.x264.ac3.mkv -vf fps=10,scale=320:-1 $filename%05d.png

Ajout du texte

user@host:~$ for i in 000*; do posX=$RANDOM;let 'posX %= 5'; posY=$RANDOM;let 'posY %= 15'; convert "$i" -font Impact -gravity south -pointsize 40 -stroke black -fill white -strokewidth 1 -annotate +"$posX"+"$posY" 'WARRRMMM!' Texted_${i}; done
for i in 000*
do
	posX=$RANDOM
	let 'posX %= 5'
	posY=$RANDOM;
	let 'posY %= 15'
	convert "$i" -font Impact -gravity south -pointsize 40 -stroke black -fill white -strokewidth 1 -annotate +"$posX"+"$posY" 'WARRRMMM!' Texted_${i}
done

Conversion des fichiers images vers un fichier GIF

user@host:~$ convert -loop 0 Texted_*.png myimage.gif

Résultat

Jim Carrey dans Ace Ventura en Afrique, Warm!!

Texte qui s'agrandit

Convertir la séquence vidéo en fichiers png

user@host:~$ ffmpeg -ss 4:09 -t 2 -i /movies/1991.Armour.of.God.2.1080p.x264.mkv -vf fps=10,scale=320:-1 $filename%05d.png

Ajout du texte

user@host:~$ a=20; for i in 000*; do convert "$i" -font Impact -gravity south -pointsize "$a" -stroke black -fill white -strokewidth 1 -annotate +0+0 'OK!' Texted_${i}; ((a+=3)); done
a=20
for i in 000*
do
	convert "$i" -font Impact -gravity south -pointsize "$a" -stroke black -fill white -strokewidth 1 -annotate +0+0 'OK!' Texted_${i}
	((a+=3))
done

Conversion des fichiers images vers un fichier GIF

user@host:~$ convert -loop 0 Texted_*.png myimage.gif

Résultat

Jackie Chan dans Opération Condor, OK!

Simuler un Zoom

Intro

Les outils Imagemagick permettent de faire pas mal de choses comme de simuler un zoom. Voyons cela avec l'exemple ci-dessous.

Convertir la séquence vidéo en fichiers png

user@host:~$ ffmpeg -ss 1:00:20 -t 2 -i /movies/1994.Street.Fighter.720P.x264.AC3.mkv -vf fps=10,scale=320:-1 $filename%05d.png

Ajout du texte

user@host:~$ for i in 000*; do cp "$i" Text_"$i"; done
user@host:~$ for i in 0000[7-9]*; do convert "$i" -font Impact -gravity south -pointsize "35" -stroke black -fill white -strokewidth 1 -annotate +0+0 'OF COURSE!'  Text_"$i"; done
user@host:~$ for i in 0001[0-4]*; do convert "$i" -font Impact -gravity south -pointsize "35" -stroke black -fill white -strokewidth 1 -annotate +0+0 'OF COURSE!'  Text_"$i"; done

Zoomer en fin de séquence

user@host:~$ a=110; b=10; for i in $(seq 20 30); do convert Text_00018.png -resize "$a"% Text_000"$i"_.png; convert -gravity center -crop 320x133+$b+0 +repage Text_000"$i"_.png Text_000"$i".png ;((a+=30)); ((b+=25)); done; rm *_.png
a=110
b=10
for i in $(seq 20 30); do 
	convert convert Text_00018.png -resize "$a"% Text_000"$i"_.png
	convert -gravity center -crop 320x133+$b+0 +repage Text_000"$i"_.png Text_000"$i".png
	((a+=30))
	((b+=25))
done
rm *_.png

Make your GIF

user@host:~$ convert -loop 0 Text_*.png myimage.gif

Enjoy the result

Street Fighter the movie Mr Bison Raul Julia Of Course!

Réduire la taille d'un GIF

Selon vers où l'on souhaite partager son GIF, la taille peut compter. Par exemple pour envoyer un GIF par MMS la taille ne doit pas dépasser 600Ko, sinon il sera soit rejeté ou automatiquement compressé par le téléphone, avec souvent une qualité aléatoire.

Voyons différentes solutions pour réduire la taille d'un GIF.

Taille avec parametres standards

user@host:~$ ffmpeg -ss 17:05 -t 8 -i /movies/1994.Pulp.Fiction.MULTI.mkv -vf fps=10,scale=320:-1 $filename%05d.png
user@host:~$ convert -loop 0 00* myimage.gif
user@host:~$ du -sh myimage.gif
2,3M    myimage.gif
Samuel L. Jackson dans Pulp Fiction, en train de boire du soda

Utiliser palettegen

user@host:~$ ffmpeg -y -ss 17:05 -t 8 -i /movies/1994.Pulp.Fiction.MULTI.mkv -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png
user@host:~$ ffmpeg -y -ss 17:05 -t 8 -i /movies/1994.Pulp.Fiction.MULTI.mkv -i palette.png -filter_complex "fps=10,scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse" output.gif
user@host:~$ du -sh output.gif
1,7M    output.gif
Samuel L. Jackson dans Pulp Fiction, en train de boire du soda

Compresser avec l'option fuzz

Cela va réduire la taille de notre GIF en détériorant (un peu) la qualité. On peut obtenir de très bons résultats si il n'y a pas trop de mouvements dans la séquence à compresser.

user@host:~$ convert myimage.gif -fuzz 2% -layers Optimize result.gif; du -sh result.gif
user@host:~$ du -sh result.gif
1,5M    result.gif
Samuel L. Jackson dans Pulp Fiction, en train de boire du soda
user@host:~$ convert myimage.gif -fuzz 5% -layers Optimize result.gif
user@host:~$ du -sh result.gif
720K    result.gif
Samuel L. Jackson dans Pulp Fiction, en train de boire du soda

Fuzz + palettegen

user@host:~$ ffmpeg -y -ss 17:05 -t 8 -i /movies/1994.Pulp.Fiction.MULTI.mkv -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png
user@host:~$ ffmpeg -y -ss 17:05 -t 8 -i /movies/1994.Pulp.Fiction.MULTI.mkv -i palette.png -filter_complex "fps=10,scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse" out%05d.png
user@host:~$ convert -loop 0 out000* myimage.gif; du -sh myimage.gif
user@host:~$ convert myimage.gif -fuzz 2% -layers Optimize result.gif; du -sh result.gif
1,1M    result.gif
Samuel L. Jackson dans Pulp Fiction, en train de boire du soda
user@host:~$ convert myimage.gif -fuzz 5% -layers Optimize result.gif; du -sh result.gif
536K    result.gif
Samuel L. Jackson dans Pulp Fiction, en train de boire du soda

Réduire la résolution

On peut aussi diminuer la résolution de notre GIF

user@host:~$ for i in 00*; do convert "$i" -resize 240x Scalled_$i; done
user@host:~$ convert -loop 0 Scalled_000* myimage.gif; du -sh myimage.gif
1,3M	myimage.gif
Samuel L. Jackson dans Pulp Fiction, en train de boire du soda

Drop frames + Fuzz

On peut aussi ne prendre qu'une frame (image) sur deux.

user@host:~$ ffmpeg -y -ss 17:05 -t 8 -i /movies/1994.Pulp.Fiction.MULTI.mkv -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png
user@host:~$ ffmpeg -y -ss 17:05 -t 8 -i /movies/1994.Pulp.Fiction.MULTI.mkv -i palette.png -filter_complex "fps=10,scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse" out%05d.png
user@host:~$ convert -delay 22 -loop 0 $(ls out000* | grep -E "*[02468].png") myimage.gif; du -sh myimage.gif
1,1M	myimage.gif
user@host:~$ convert myimage.gif -fuzz 5% -layers Optimize result.gif; du -sh result.gif
340K	result.gif
Samuel L. Jackson in Pulp Fiction, dans Pulp Fiction, en train de boire du soda
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Contact :