
Obwohl es mittlerweile eine ganze Reihe grafischer Softwarepakete zur Verwaltung von Bildern gibt, stößt der ambitionierte Digital-Knisper immer wieder auf Aufgaben, die sich mit diesen Werkzeugen nur recht umständlich oder überhaupt gar nicht bewältigen lassen. Aus purer Ernüchterung über diese enttäuschende Situation habe ich mich vor längerer Zeit mal auf die Suche nach Alternativen gemacht und Abhilfe in einer Reihe von freien CLI-Programmen gefunden, die mir eine ganze Menge eintöniger Arbeit ersparen …
Grob umrissen lassen sich die automatisierbaren Aufgaben in zwei Bereiche unterteilen: Der eine befasst sich nicht mit dem Bilddaten selbst, sondern mit den in der Bilddatei enthaltenen Metadaten - das sind jene Informationen, die nicht zur Darstellung des Bildinhalts an sich benötigt werden, sondern etwa Auskunft über den Zeitpunkt der Entstehung des Bildes oder den Urheber geben. In diesem Aufgabenbereich geht's unter anderem um das automatische Benennen und Sortieren der Bilddateien und die gezielte Manipulation der von der Kamera generierten EXIF-Daten. Der andere dreht sich um einfache Bildbearbeitungs-Aufgaben wie z.B. das Skalieren und Rotieren der Bilder oder auch die automatisierte Erstellung von Thumbnails. Für den Metadaten-Sektor kommen bei mir exiv2 und jhead zum Einsatz, für die automatisierte Bildbearbeitung hingegen eignet sich die überaus mächtige Kommandozeilen-Schnittstelle von ImageMagick, wobei ich für Verarbeitungsschritte, die sich ohne verlustbehaftete Neukodierung erledigen lassen (wie z.B. das Rotieren des Bildinhalts um 90, 180 oder 270 Grad) zur Verwendung von jpegtran rate. All diese Werkzeuge sind im Übrigen nicht nur für unixoide Systeme, sondern auch für Windows verfügbar.
Im Folgenden möchte ich dem Komfort dieser Helferlein huldigen, indem ich ein paar typische Probleme beim Organisieren und Publizieren von Digitalbildern vorstelle und zeige, wie man sie mit den genannten Programmen lösen lassen.
Ich weiß nicht, wie es sich bei Geräten anderer Hersteller verhält, aber zumindest meine Kamera ist bei der Benennung der mit ihr erzeugten Bilder nicht besonders kreativ. Wenn ich die Fotos von der Speicherkarte herunterlade, bin ich mit einem ganzen Haufen Dateien konfrontiert, die allesamt nach einem Schema benannt sind, das in etwa so aussieht: pictxxxx.jpg - xxxx ist dabei eine vierstellige, laufende Nummer, von der man zwar auf die Abnützung der Kamera schließen kann, die aber ansonsten keinelei verwertbare Information beinhaltet.
Besser wär's, wenn ich vom Dateinamen zumindest auf den Zeitpunkt der Aufnahme schließen könnte - und genau das, nämlich das Umbennen der Bilder anhand des im EXIF-Header gespeicherten Datums, ist mit exif2 überhaupt kein Problem.
Angenommen, die frisch von der Kamera geladenen Fotos liegen alle im gegenwärtigen Verzeichnis und ich möchte, dass eine Datei nicht pict5644.jpg heißt, sondern eher so ähnlich wie 2006-12-31--22-35-54.jpg, dann reicht folgender Kommandozeilen-Aufruf:
exiv2 -r %Y-%m-%d--%H-%M-%S mv *.jpg
Der Parameter mv teilt exiv2 mit, dass die übergebenen Dateien (*.jpg) anhand des EXIF-Erstellungsdatums umbenannt werden sollen - und zwar entsprechend des mit der Option -r übergebenen Format-Strings. Der Format-String ist im Wesentlichen beliebig wählbar und wird so interpretiert, wie der format-Parameter der glibc-Funktion strftime - mit der Besonderheit, dass es noch ein paar zusätzliche Schlüsselwörter gibt, die es z.B. erlauben, Teile des ursprünglichen Dateinamens zu erhalten. Zur Demonstration noch ein kleines Beispiel:
exiv2 -r %F_:basename: mv *.jpg
Eine Datei, die pict5863.jpg heißt, würde mit obiger Anweisung z.B. zu 2007-01-10_pict5863.jpg umbenannt - das Schlüsselwort :basename: im Format-String wird also durch den ursprünglichen Namen der Datei (ohne Endung) ersetzt.
Eine Kleinigkeit noch: Wenn mehrere Dateien einen Namen erhalten würden, der bereits belegt ist, fragt exiv2 nach, wie es sich verhalten soll. Diese Nachfrage kann mit der Option -F unterdrückt werden - in dem Fall wird der neue Name automatisch mit einer Nummer erweitert, um den Namenskonflikt aufzulösen.
Viele Kameras und auch manche Bildbearbeitungsprogramme hinterlassen zusätzliche Informationen in den Bilddateien, die man vielleicht gar nicht benötigt. Weit verbreitet ist zum Beispiel das in JPEG-Dateien eingebettete Vorschaubild, das eigentlich kaum einen praktischen Verwendungszweck hat: Für eine brauchbare Vorschau ist es zu klein und oft auch zu riguros komprimiert - zudem erstellen und verwenden viele Bildbetrachter ohnehin eigene Thumbnail-Indizes.
Es wäre also naheliegend, sich dieser Last zu entledigen - ganz besonders, wenn man plant, das Bild über's Netz zu verbreiten, wo für viele Benutzer immer noch jedes gesparte Kilobyte zählt. Zur nebenwirkungsfreien Entfernung bieten sich sowohl exiv2, als auch jhead an, wobei es letzteres erlaubt, zusätzliche Metadaten (solche, die weder ein JPEG-Kommentar, noch im EXIF-Header enthalten sind) zu entfernen.
Mit exiv2 sieht ein Kommandozeilenaufruf in etwa so aus:
exiv2 -d t *.jpg
Wer nicht nur das Thumbnail, sondern auch eventuell vorhandene Nicht-EXIF-Daten loswerden möchte, kann das mit jhead tun:
jhead -dt -du *.jpg
Wie eingangs erwähnt, bleiben alle anderen EXIF-Daten und JPEG-Kommentare verschont. Wer im Übrigen meint, der so eingesparte Platz wäre ohnehin lächerlich gering, der sei hiermit eines besseren belehrt: Ein kurzer Testlauf über ca. 100 frisch aus der Kamera gepresste Bilder zeigte eine Einsparung von knapp 5 MB.
Ein wesentliches Problem bei JPEG und anderen verlustbehafteten Kompressionsformaten ist, dass das Bearbeiten der Bildinformationen im Regelfall eine Neukodierung erforderlich macht, die sich negativ auf die Bildqualität auswirkt. Im Falle von JPEG gibt es jedoch ein Verfahren, das es erlaubt, das Bild um 90 Grad zu drehen, ohne die für die Qualität schadhaften Stufen der JPEG-Kodierung erneut zu durchlaufen (für Interessierte: Das Verfahren ist in diesem lesenswerten Artikel von Guido Vollbeding genauer beschrieben).
Der Wunsch, Bilder permanent (also nicht nur für die Anzeige) im oder gegen den Uhrzeigersinn rotieren zu wollen, ist vermutlich jedem bekannt, der ab und an hochformatige Bilder mit einer Querformat-Kamera macht - eher selten hingegen benötigt man die anderen von jpegtran angebotenen Tranformationen (jpegtran erlaubt beispielsweise auch das vertikale und horizontale Spiegeln, sowie die Umwandlung in Graustufen durch Verwerfen des Chrominanz-Kanal). Aufgrund der technischen Umsetzung des Verfahrens ist es für die meisten Operationen erforderlich, dass sowohl die horizontale, als auch die vertikale Auflösung des Ursprungsbildes ganzzahlige Vielfache der Blockgröße sind - im Regelfall sollten Breite und Höhe also durch 8 teilbar sein.
Ein Kommandozeilenaufruf zur Drehung im Uhrzeigersinn sieht z.B. so aus:
jpegtran -trim -optimize -rotate 90 -copy all -outfile out.jpg in.jpg
Hier wird eine um 90 Grad rotierte Kopie von in.jpg in die Datei out.jpg geschrieben. Die Option -copy all sorgt dafür, dass alle Metadaten erhalten bleiben, dank -trim werden Teile des Bildes, die aufgrund der Beschränkung auf ganze Blöcke nicht tranformiert werden können (üblicherweise maximal 7 Pixel in Breite und Höhe), abgeschnitten.
Die Kommandozeilenoption -optimize hingegen verdient nähere Betrachtung, denn sie dient dem...
Bei JPEG-Dateien bietet sich zusätzlich zum Entfernen nicht benötigter Metadaten noch eine weitere Möglichkeit zur Reduktion des Speicherbedarfs, bei der die Bildqualität nicht angekratzt wird: Das Optimieren der Parameter der Entropie-Kodierung. Ohne näher auf Details eingehen zu wollen kann man die Entropie-Kodierung als einen der letzten Bearbeitungsschritte bei der Erstellung von JPEG-Dateien beschreiben, der dazu dient, die bereits aufbearbeiteten Bilddaten in eine möglichst kompakte Form zu pressen. Die dabei zum Einsatz kommenden Methoden ähneln denen, die auch bei medienunabhängigen Kompressionformaten (wie z.B. zip,
gz oder bzip2) eingesetzt werden.
Weil eine gute Entropie-Kodierung Rechenzeit kostet, die Geschwindigkeit, mit der eine Digitalkamera ein Bild abspeichert im täglichen Gebrauch aber möglichst kurz sein sollte, ist bei vielen von der Kamera-Hardware kodierten Bildern noch Luft nach oben - die nachträgliche Wiederholung dieses Schrittes kann sich also durchaus auszahlen, wenn Plattenplatz knapp oder Bandbreite kostbar ist.
Jeder, der schon mal nach der Umstellung auf Sommerzeit vergessen hat, die Uhrzeit seiner Kamera zu korrigieren, schätzt die Möglichkeit, die in den Bilddateien eingebetteten EXIF-Daten nachträglich bearbeiten zu können. Mit exiv2 lassen sich jedoch auch weitaus umfassendere Änderungen an den Metadaten durchführen als bloß die Korrektur der Uhrzeit und des Datums.
So kann man z.B. EXIF-Eigenschaften, die eine Kamera nicht von sich aus bestimmen kann (man denke an textuelle Beschreibungen des Bildinhalts oder den Namen des Photographen) nachträglich einfügen oder unerwünschte Metadaten entsorgen.
Eine Bilddatei in.jpg, bei der die Zeit um eine Stunde zurückhinkt und der man noch Urheberinformation und einen Kommentar hinzufügen möchte, ließe sich z.B. folgendermaßen ergänzen:
exiv2 -a 01:00:00 in.jpg
exiv2 -M'set Exif.Image.ImageDescription Irgendein Foto' in.jpg
exiv2 -M'set Exif.Image.Artist John Doe' in.jpg
exiv2 -M'set Exif.Image.Copyright Copyright, John Doe, 2007.' in.jpg
Dabei ist zu beachten, dass die dem Parameter -M übergebene Aktion set eine bestehende EXIF-Eigenschaft gleichen Namens
überschreibt - existiert der angegebene Schlüssel hingegen noch nicht, wird er hinzugefügt.
Analog dazu lassen sich bestehende Schlüssel auch entfernen. Möchte man z.B. die verwendete Ausstattung vor potenziellen Neidern geheimhalten, so lassen sich die relevanten Schlüssel leicht aus der Bilddatei tilgen:
exiv2 -M'del Exif.Image.Make' in.jpg
exiv2 -M'del Exif.Image.Model' in.jpg
exiv2 -M'del Exif.Image.Software' in.jpg
Eine Übersicht über die Eigenschaften, die exiv2 bekannt sind, findet sich hier.
Manchmal möchte man mehrere Versionen der eigenen Fotos in unterschiedlichen Auflösungen erzeugen - sei es, um sie in einer Web-Galerie mit Thumbnail-Vorschau zu publizieren oder um eine kleinere Version der Bilder für den E-Mail-Versand vorzuhalten. Hat man gerade keine Bildbearbeitungssoftware mit Stapelverarbeitungsfunktion parat, artet die Generierung der skalierten Bilder schnell zu einer mühsamen Angelegenheit aus - vor allem, wenn man vor dem Verkleinern etwa noch die Bildschärfe nachbessern möchte.
Recht komfortabel lässt sich dieses Problem mit der überaus mächtigen Kommandozeilenschnittstelle von ImageMagick lösen. Eine vorgeschärfte und nach dem Lanczos-Verfahren skalierte Version eines Bildes lässt sich z.B. mit folgendem Aufruf erstellen:
convert -filter Lanczos -quality 80 in.jpg \
-unsharp 0x0.6+1.0 -resize 800x800 out.jpg
Der Parameter -quality bestimmt dabei die (JPEG-)Qualitätseinstellung der erzeugten Bilddatei, mit -filter wird das Skalierungsverfahren ausgewählt und -unsharp sowie -resize bestimmen und parametrisieren die durchzuführenden Operationen. Bei der Skalierung bleibt das ursprüngliche Seitenverhältnis des Bildes erhalten - nicht-quadratische Bilder werden also weder auf 800x800 aufgeblasen noch vertikal oder horizontal beschnitten, sondern gewissermaßen in einen Rahmen der Größe 800x800 eingepasst (je nach Seitenverhältnis kann daher entweder die Breite oder die Höhe des resultierenden Bildes kleiner als 800 Pixel sein).
Nicht zuletzt aufgrund der (zu Beginn vielleicht abschreckenden) Komplexität der Kommandozeilenschnittstelle lassen sich mit einem einzigen Aufruf auch gleich mehrere Ausgabedateien erzeugen. Ohne näher auf die Details der etwas gewöhnungsbedürftigen Syntax eingehen zu wollen (das würde den Umfang dieses Artikels wahrlich sprengen), sei hier ein Beispiel angeführt, das aus einer Eingabedatei vier unterschiedlich aufgelöste Bilder mit verschiedenen JPEG-Qualitätseinstellungen erzeugt:
convert -filter Lanczos in.jpg -unsharp 0x0.6+1.0 \
\( +clone -resize 128x128 -quality 60 -write out_128.jpg +delete \) \
\( +clone -resize 256x256 -quality 70 -write out_256.jpg +delete \) \
\( +clone -resize 640x640 -quality 80 -write out_640.jpg +delete \) \
\( +clone -resize 800x800 -quality 85 -write out_800.jpg +delete \) \
null:
Leider ist es - zumindest meines bescheidenen Wissens nach - nicht ohne weiteres Möglich, einen Aufruf wie diesen so umzuschreiben, dass er sich problemlos auf mehrere Eingabedateien anwenden lässt. Mit ein bisschen Shell-Zauberei stellt aber auch das kein Problem mehr dar. Folgendes Skript akzeptiert als Parameter beliebig viele Eingabedateien und erzeugt im gegenwärtigen Arbeitsverzeichnis eine Reihe von skalierten Versionen:
Listing: batchscale.sh
#!/bin/sh
if [ $# = 0 ]; then
echo 'Usage: batchscale.sh [FILE]...' 1>&2
exit 0
fi
while [ "$1" != "" ]; do
IF=`echo "$1" | grep -o '[^/]*$'`
IE=`echo "$IF" | grep -o '\.[^\.]*$'`
IB=`expr substr "$IF" 1 \( \( length "$IF" \) - \( length "$IE" \) \)`
echo "Converting $1..."
convert "$1" -quality 85 -unsharp 0x0.6+1.0 \
\( +clone -resize 1280x960 -write "./${IB}_L${IE}" +delete \) \
\( +clone -resize 640x480 -write "./${IB}_M${IE}" +delete \) \
\( +clone -resize 160x120 -write "./${IB}_T${IE}" +delete \) \
null:
shift
done
Mit ImageMagick lassen sich freilich auch noch eine ganze Menge anderer Dinge machen. Die Anwendungsfelder reichen vom skriptgesteuerten Erstellen von Collagen über das automatisierte Anwenden verschiedener Filter bis hin zur vollständigen Synthese von Bildinhalten. Für Interessierte stellt eine weitergehende Beschäftigung mit diesem Paket daher sicher keine Zeitverschwendung dar.
Puh, jetzt ist mein Plädoyer für die Verwendung von Kommandozeilenprogrammen doch ein bisschen umfangreicher ausgefallen, als ursprünglich angedacht. Ich hoffe, mir ist es zumindest ein klein wenig gelungen, zu veranschaulichen, dass die Zeit dieser nützlichen Helferlein noch lange nicht abgelaufen ist - zumindest, wenn man nach zeitsparenden Möglichkeiten sucht, wiederkehrende Abläufe zu automatisieren.
Über Kommentare und Beispiele für die kreative Anwendung würde ich mich überaus freuen.
Comments
Wolle
Oh Mann, DANKE für diesen Artikel. Mein Einstieg in die Kommandozeilentools zur Bildbearbeitung hat einen super Impuls bekommen. Wegen sowas wie diesem Artikel hat das Internet einen Sinn.
Waidele_Kommentar
Nun ja, man kann die Convert-Orgie schon in einer Zeile ausdrücken:
—8<——————————————————————
for i in *.jpg ; do convert -filter Lanczos $i -unsharp 0×0.6+1.0 \( +clone -resize 128×128 -quality 60 -write 128_$i +delete \) \( +clone -resize 256×256 -quality 70 -write 256_$i +delete \) \( +clone -resize 640×640 -quality 80 -write 640_$i +delete \) \( +clone -resize 800×800 -quality 85 -write 800_$i +delete \) null: ; done
—8<——————————————————————
Ob das aber sinn macht, ist natürlich die andere Frage… :)
Ergänzt ganz prima meinen eigenen Shell-Workflow für Bilder, den ich unter stamped_and_categorized und sometime_in_summertime
beschrieben habe.
Dankeschön vielmals!
Post new comment