ImageMagick is een verzameling hulpprogramma’s die we kunnen gebruiken om rasterafbeeldingen te maken en te manipuleren.
Het conversiehulpprogramma van ImageMagick wordt gebruikt om
afbeeldingen tussen verschillende afbeeldingsformaten te converteren.
Naast het primaire gebruik kunnen we ook het formaat wijzigen,
bijsnijden, optimaliseren, vervagen, tekenen en effecten op afbeeldingen
toepassen.
ImageMagick is niet standaard beschikbaar op de meeste
Linux-distributies. We kunnen het echter vanuit onze pakketrepository
installeren onder de pakketnaam imagemagick met behulp van een
pakketbeheerder.
GIF-animatie maken met converteren
We kunnen eenvoudig een animatie maken uit een aantal PNG-bestanden met de volgende syntaxis:
convert [OPTIONS] [GLOB_PATTERN] [OUTPUT_FILE]
We kunnen GLOB_PATTERN opgeven als *.png, ervan uitgaande dat de PNG-bestanden op volgorde staan:
static-image-01.png
static-image-02.png
static-image-03.png
static-image-04.png
…
static-image-n.png
Laten we nu, als onze afbeeldingen op volgorde staan, de GIF-animatie maken:
convert -delay 10 -loop 0 *.png anim.gif
Laten we het opsplitsen:
de optie
-delay wordt gebruikt om de vertraging tussen elk frame weer te geven
het argument 10 voor de optie -delay wordt toegewezen aan 10 x 10,
wat resulteert in een vertraging van 100 ms
-loop geeft aan of we de animatie willen herhalen, waarbij 0 waar is en 1 onwaar
*.png is het globale-patroon voor de PNG-bestanden die we als invoer hebben gebruikt
anim.gif is onze resulterende GIF-animatie
De optie -delay verwacht tijd in honderdste seconden. Eén honderdste seconde is
gelijk aan 0,01 seconde. Daarom is 10 100 milliseconden en is een -delay
van 100 één seconde.
Organiseren
Als we PNG-bestanden hebben die op volgorde staan en waarvan de namen
niet op nul zijn opgevuld, zal onze resulterende GIF-animatie niet
correct zijn. Stel dat dit de naam is van onze PNG-bestanden:
static-image-0.png
static-image-1.png
static-image-3.png
static-image-4.png
static-image-5.png
…
static-image-22.png
Vervolgens zal onze shell deze bestandsnamen als volgt interpreteren:
static-image-1.png
static-image-10.png
static-image-11.png
…
static-image-19.png
static-image-2.png
…
Om die reden zullen de frames in onze resulterende GIF niet op hun
plaats zijn en niet animeren zoals we verwachten. Gelukkig zijn er twee
oplossingen voor dit probleem. De voor de hand liggende oplossing zou
zijn om voorloopnullen aan de bestandsnamen toe te voegen:
for a in [0-9]*.txt; do
mv $a `printf %04d.%s ${a%.*} ${a##*.}`
done
Als alternatief kunnen we de bestandsnamen correct sorteren:
ls -1 | sort -n -t'-' -k3
De tweede oplossing is handig omdat we opdrachtvervanging kunnen
gebruiken om de GIF-animatie te maken terwijl onze bestandsnamen intact
blijven:
convert -delay 10 -loop 0 $(ls -1 | sort -n -t'-' -k3) anim.gif
Afhankelijk van de gegeven PNG-afbeeldingen kan de bestandsgrootte
van onze resulterende GIF groot zijn. Gelukkig is er nog een
ImageMagick-hulpprogramma genaamd mogrify, dat we kunnen gebruiken om de
GIF te optimaliseren.
mogrify lijkt op converteren, maar mogrify schrijft naar het originele afbeeldingsbestand.
Laten we de grootte van ons GIF-bestand controleren:
ls -lh anim.gif
-rw-r--r-- 1 hey hey 1.8M Aug 4 16:09 anim.gif
Laten we het nu optimaliseren:
mogrify -layers optimize -fuzz 10% anim.gif
Afhankelijk van de GIF-bestandsgrootte kan dit lang duren. Als onze
afbeelding is geoptimaliseerd, kunnen we de grootte ervan controleren:
-rw-r--r-- 1 hey hey 755K Aug 4 16:34 anim.gif
Alternatief: FFmpeg
FFmpeg is een krachtig opdrachtregelprogramma dat wordt gebruikt om multimediabestanden en streams te manipuleren en verwerken.
FFmpeg wordt standaard niet meegeleverd met de meeste
Linux-distributies. In dat geval kunnen we het vanuit onze
pakketrepository installeren met de pakketnaam ffmpeg.
Nadat FFmpeg is geïnstalleerd, laten we het verifiëren:
ffmpeg -v
ffmpeg version n5.0.1 Copyright (c) 2000-2022 the FFmpeg developers
built with gcc 12.1.0 (GCC)
3.1. Een GIF maken met FFmpeg
Net als bij converteren voeden we onze invoer-PNG-bestanden naar
FFmpeg, passen enkele opties toe en specificeren de uitvoerbestandsnaam
die eindigt met de extensie .gif:
ffmpeg -framerate 60 -pattern_type glob -i '*.png' -r 30 anim.gif
Laten we het opsplitsen:
-pattern_type specificeert het type patroon dat we kunnen gebruiken om gemakkelijk onze afbeeldingen te selecteren
-framerate optie verwacht het aantal frames per seconde voor het uitvoerbestand
-i optie specificeert onze invoer-PNG-bestanden als een glob-patroon
-r geeft aan hoe afbeeldingen moeten worden gekozen op basis van de framerate die we hebben opgegeven
We hebben onze uitvoerbestandsnaam opgegeven als anim.gif. FFmpeg berekent het doelformaat uit de extensie.
De optie -r die we hebben gebruikt, is interessant. Het wordt
gebruikt om frames per seconde op te geven. We hebben dit echter al
gespecificeerd in de optie -framerate. Het probleem hier is dat
afbeeldingsbestanden geen framerates hebben.
Daarom zal FFmpeg, door gebruik te maken van -framerate en -r, dit
interpreteren als 60/30. Omdat 60/30 resulteert in 2, zal FFmpeg elke
twee afbeeldingen een afbeelding kiezen. Dit kan ons wat ruimte besparen
als we het nodig hebben. We hoeven deze optie echter helemaal niet te
specificeren.
Als alternatief kunnen we de opdracht inkorten:
ffmpeg -pattern_type glob -i "*.png" -r 60/30 out.gif
3.2. Het optimaliseren van de GIF
Standaard is FFmpeg redelijk goed in het optimaliseren van onze
uiteindelijke uitvoer. Hier is de grootte van de GIF zonder de
frames-optie:
ls -lh anim.gif
-rw-r--r-- 1 hey hey 907K Aug 5 00:56 anim.gif
Met de optie -r 60/30 is de uitvoer relatief klein:
ls -lh anim.gif
-rw-r–r– 1 hey hey 83K Aug 5 01:04 anim.gif
Als alternatief kunnen we ook een schaalfilter toepassen om de grootte te verkleinen:
ffmpeg -pattern_type glob -i “*.png” -vf scale=512:-1 anim.gif
-vf geeft aan dat we een videofilter willen toepassen
het schaalfilter geeft aan dat we de uiteindelijke afbeelding willen schalen
Het argument 512:-1 geeft de breedte en hoogte van de GIF aan
Het argument -1 voor hoogte betekent dat we onze hoogte evenredig willen houden met de breedte van de GIF.
Laten we de bestandsgrootte controleren nadat we de opdracht hebben uitgevoerd:
ls -lh anim.gif
-rw-r–r– 1 hey hey 636K Aug 5 01:07 anim.gif
We kunnen het schaalvideofilter combineren met de frameoptie om nog kleinere GIF’s te krijgen.