logo rss

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

  • Ici depuis Debian :
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.

  • Frames : 10 par seconde
  • Résolution : 320
  • Temps de début : 2:14
  • Durée : 6 seconds
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:~$ magick -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

  • On récupère les informations sur les dimensions
user@host:~$ identify 00039.png 00039.png PNG 320x180 320x180+0+0 8-bit sRGB 79528B 0.000u 0:00.000
  • Ici nous avons une résolution de 320 sur 180 pixels. Et nous avons deux fois 25 pixels à supprimer en haut et en bas de nos images :
capture du film american psycho avec patrick bateman et la taille de l'image en pixel
  • Recadrage de l'image :

Nous allons passer de 180 à 130 pixels en hauteur (180-25-25=130) : user@host:~$ magick -crop 320x130+0+25 00039.png +repage Cropped_00039.png

  • Ce qui donne :
capture du film american psycho avec patrick bateman et la taille de l'image en pixel
  • Pour recadrer l'ensemble de nos images :
user@host:~$ for i in 000*; do magick -crop 320x130+0+25 "$i" +repage Cropped_"$i"; done

Conversion des fichiers images vers un fichier GIF

user@host:~$ magick -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

  • -font : utiliser la commande convert -list font pour voir les polices disponibles
  • -pointsize : taille du texte
  • -annotate +0+0 : position du texte
  • '\'' : caractères d'échapement pour '
  • \n : Retour à la ligne
user@host:~$ magick 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
  • Ce qui donne :
Jeff Bridges dans The Big Lebowski, t'es un sale con!

Ajouter du texte à plusieurs images

  • On copie d'abord toutes les images vers de nouveaux fichiers :
user@host:~$ for i in 000*; do cp "$i" Text_"$i"; done
  • On ajoute le texte sur toutes les images que l'on souhaite (ici de l'image 00016.png à 00027.png) :
user@host:~$ for i in 0001[6-9]*; do magick "$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 magick "$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:~$ magick -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.

  • Depuis un Windows récupérer la Police Impact (C:\Windows\Fonts\impact.ttf) :
Windows Fonts Directory Impact
  • Créer un nouveau répertoire Windows fonts :
root@host:~# mkdir /usr/share/fonts/WindowsFonts
  • Copier le fichier impact.ttf vers notre dossier /usr/share/fonts/WindowsFonts nouvellement créé :
root@host:~# mv impact.ttf /usr/share/fonts/WindowsFonts/
  • On lance une regenération de notre cache de polices :
user@host:~$ fc-cache --force
  • Faisons un test :
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
  • Notez qu'on utilise maintenant l'option -font Impact :
user@host:~$ for i in 0000[2-7]*; do magick "$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 magick "$i" -font Impact -gravity south -pointsize "55" -stroke black -fill white -strokewidth 1 -annotate +0+0 'T'\''ES GIVRÉ!' Text_"$i"; done user@host:~$ magick -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

  • $a : position du texte
  • a=-250 : position de départ du texte
  • ((a+=60)) : vitesse de défilement du texte
user@host:~$ a=-250;for i in 000*; do magick "$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
  • Même chose qu'au dessus mais plus facile à lire :
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:~$ magick -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

  • $posX : position horizontale du texte
  • $posY : position verticale du texte
user@host:~$ for i in 000*; do posX=$RANDOM;let 'posX %= 5'; posY=$RANDOM;let 'posY %= 15'; magick "$i" -font Impact -gravity south -pointsize 40 -stroke black -fill white -strokewidth 1 -annotate +"$posX"+"$posY" 'WARRRMMM!' Texted_${i}; done
  • Même chose qu'au dessus mais plus facile à lire :
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:~$ magick -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

  • a=20 : text start size
  • ((a+=3)) : text growing speed
user@host:~$ a=20; for i in 000*; do magick "$i" -font Impact -gravity south -pointsize "$a" -stroke black -fill white -strokewidth 1 -annotate +0+0 'OK!' Texted_${i}; ((a+=3)); done
  • Même chose qu'au dessus mais plus facile à lire :
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:~$ magick -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

  • Voir ici pour plus de détails.
user@host:~$ for i in 000*; do cp "$i" Text_"$i"; done user@host:~$ for i in 0000[7-9]*; do magick "$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 magick "$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 magick Text_00018.png -resize "$a"% Text_000"$i"_.png; magick -gravity center -crop 320x133+$b+0 +repage Text_000"$i"_.png Text_000"$i".png ;((a+=30)); ((b+=25)); done; rm *_.png
  • Même chose qu'au dessus mais plus facile à lire :
    • Text_00018.png : frame sur laquelle sera effectué le zoom, ici la dernière de la séquence
    • a=110 : première valeur du Zoom
    • b=10 : première valeur du décalage du cadre vers la droite
    • $(seq 20 30) : nombre de frames sur lequel un zoom sera effectué (ici : Text_00020.png à Text_00030.png)
    • ((a+=30)) : incrément du zoom pour chaque frame
    • ((b+=25)) : incrément du décalage vers la droite pour chaque frame
    • rm *_.png : suppression des fichiers temporaires
a=110 b=10 for i in $(seq 20 30); do convert magick 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

Conversion des fichiers images vers un fichier GIF

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

Résultat

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:~$ magick -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:~$ magick 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:~$ magick 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:~$ magick -loop 0 out000* myimage.gif; du -sh myimage.gif user@host:~$ magick 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:~$ magick 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

  • Passer de 320 à 240 :
user@host:~$ for i in 00*; do magick "$i" -resize 240x Scalled_$i; done user@host:~$ magick -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:~$ magick -delay 22 -loop 0 $(ls out000* | grep -E "*[02468].png") myimage.gif; du -sh myimage.gif 1,1M myimage.gif user@host:~$ magick 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 :

adresse mail de contact