Neulich habe ich einen Vortrag zu meinem digitalen Fordit gehalten. Als Folien hatte ich praktisch nur Bilder, also habe ich weder LaTeX noch andere Programme genommen, die man üblicherweise für Präsentationen nutzt, sondern einfach einen Haufen Bilddateien vorgeführt.
Dazu musste dann einige Bilder noch irgendwie verwursten. Zum Beispiel einen Haufen von Höhenkarten zu einem Bild zusammenfügen, so dass man sie nebeneinander sehen kann. Oder Bildunterschriften (CC-Lizenzhinweise) in die Bilder einfügen. Natürlich kann man das auch mit Bildverarbeitungsprogrammen wie Gimp machen. Aber gerade für das Zusammenfügen von Bildern wäre das sehr fummelig geworden, und ich habe ich zwischendurch auch ein paar Mal umentschieden, welche Bilder drin sind und welche nicht.
Also wäre ein einfaches Tool praktisch, mit dem man das ganz einfach über die Kommandozeile machen kann. Und das gibt es natürlich: ImageMagick Ein Schweizer Taschenmesser für Bildbearbeitung. Bisher habe ich das meist nur zum Skalieren von Bildern verwendet. Aber es hat viele Funktionen.
Text in ein Bild einfügen mit ImageMagick
Mit ImageMagick Text in ein Bild einzufügen ist relativ umständlich, weil es sehr viele Optionen gibt. Ich wollte einfach einen Text, der das Bild unten überlagert. Das habe ich mit folgendem Befehl hingekriegt:
magick input.jpeg -font "Noto-Serif-CJK-SC" -background black -fill white -pointsize 72 -gravity South -annotate +0+2 "something copyright" output.jpeg
Damit wird die Datei input.jpeg
genommen und in der Schriftart Noto-Serif-CJK-SC
(Option -font
) in weißer Schrift (Optionn -fill white
) und Schriftgröße 72 (-pointsize 72
) unten in der Mitte des Bilders (-gravity South
) der Text something copyright
eingefügt und das Ergebnis in output.jpeg
gespeichert. Fragt mich nicht, was das -annotate +0+2
bedeutet, aber ich weiß noch, dass es wichtig war.
Wahrscheinlich wäre ein Bildbearbeitungsprogramm hier einfacher gewesen. Aber es ist trotzdem nützlich, wenn man viele Dateien mit Texten versehen möchte, oder so etwas automatisch machen muss.
Die Schriftart habe ich übrigens ausgewählt, weil eines der Bilder von einer Person namens 峠 武宏 unter eine CC-Lizenz gestellt wurde, und die Standardschriftart diese Schriftzeichen nicht enthält. Anstelle von Platzhaltern würde ImageMagick hier überhaupt nichts anzeigen. Also bei automatischer Verarbeitung vorsichtig sein!
Bilder zusammenfügen
Bilder zusammenfügen geht viel einfacher:
montage -define webp:lossless=true -background darkgreen in_1.webp in_2.webp in_3.webp in_4.webp out.webp
Damit werden alle in_?.webp
-Dateien zusammengefügt, mit jeweils ein bisschen Abstand zu allen Seiten. Dieser Abstand ist in diesem Fall dunkelgrün (um ihn von den schwarzweiß-Höhenkarten abzuheben, die in den Bildern enthalten sind). Das Ergebnis wird (verlustfrei komprimiert dank -define webp:lossless=true
) in out.webp
gespeichert.
Wichtig ist hier, dass ImageMagick die Bilder ab einer bestimmten Größe runterskaliert. Das kann man aber mit der -geometry
-Option verändern, so kann man zum Beispiel das Skalieren mit -geometry +2+2
abstellen (das +2+2
sorgt dafür, dass immer noch ein Abstand zwischen den Bildern gehalten wird, +0+0
würde bedeuten, dass es keinen Abstand gibt).
Security
Eines der schönen Dinge an Imagemagick ist, dass es sich gut zur Automatisierung eignet und einen Riesenhaufen an Bildformaten unterstützt.
Das Gefährliche an ImageMagick ist, dass es zur Automatisierung sehr weit verbreitet ist und einen Riesenhaufen an (teilweise sehr exotischen) Bildformaten unterstützt.
Fangen wir mit dem zweiten Punkt an. Parser für komplexe Dateiformate zu schreiben ist schwierig. Und alle gängigen Dateiformate sind komplex. Nur als Beispiel: ein Kollege von mir musste beruflich einmal Bilder eines Formats (Tiff, glaube ich) parsen und in ein anderes Format umwandeln. Die Idee war nicht das ganze (möglicherweise ziemlich große) Bild in den Speicher zu laden, sondern die Daten zu streamen. Stellte sich als schwierig heraus, weil das Eingangsbildformat seinen Header nicht am Anfang hatte. Also zumindest nicht immer und nicht den ganzen Header. Manchmal waren Teile davon (wie die Bilddimension) auf irgendwelche Sub-Header verteilt, die irgendwo in der Bildatei liegen konnten.
Komplexität bedeutet, dass mehr Code geschrieben werden muss und es schwieriger ist, den Code zu verstehen. Beides ist guter Nährboden für Bugs und damit für Sicherheitslücken. Bild- Video- und Audioformate sind dafür notorisch. Und ImageMagick ist in C geschrieben. Jeder Speicherfehler (z.B. weil man sich auf Größenangaben aus der Datei verlässt) ist potentiell eine Code-Execution. Das will man nicht.
Dazu kommt der erste Punkt: ImageMagick ist weit verbreitet. Viele Websites nutzen es, um im Hintergrund hochgeladene Bilder zu verarbeiten (z.B. um Thumbnails zu erstellen). Das bietet viel Angriffspotential.
Jetzt könnte man sagen: „Ist ja in Ordnung, aber ich lasse ja nur GIF- PNG- , JPEG- und WEBP-Bilder zu, und die Decoder dafür sollten ja gut genug überprüft sein. Exotische Bildformate mit schlecht getesteten Parsern brauche ich nicht.
Schön und gut, nur funktioniert ImageMagick in der Standardeinstellung nicht so. Dateinamen sind Schall und Rauch, und das gilt insbesondere auch für die Dateiendungen. Die sind nicht mehr als ein lieb gemeinter Hinweis, was in der Datei sein könnte. Eine Datei foo.webp
könnte also in Wirklichkeit eine JPEG-Datei sein. Oder irgendetwas, von dem wir noch nie gehört haben. ImageMagick versucht, das Format automatisch zu erkennen.
Automatische Erkennung ist aber schwierig. Insbesondere gibt es Künstler/Hacker, die sich einen Spaß daraus machen Dateien zu konstruieren, die mehrere gültige Dateiformate gleichzeitig sind. Das war vor zehn Jahren, der Typ ist immer noch aktiv. Es ist also schwierig hervorzusagen, mit welchem Decoder ImageMagick die Datei öffnen wird.
Man kann das Problem einschränken, indem man ImageMagick dazu zwingt, sich auf ein Format festzulegen, z.B. indem man den Namen der Inputdatei mit einem <format>:
-Prefix versieht:
convert webp:in.webp -scale 50% out.webp
Wenn in.webp
jetzt in wirklichkeit eine JPEG-Datei ist, kriege ich den folgenden Fehler:
convert: corrupt image `in.webp' @ error/webp.c/ReadWEBPImage/563.
(DISCLAIMER: es gibt vermutlich noch einen ganzen Haufen anderer Dinge, auf die man achten muss. Das hier ist nur ein Beispiel und soll keine Anleitung sein, wie man ImageMagick sicher benutzt).
Es werden auch heute noch gelegentlich Sicherheitslücken in ImageMagick gefunden. Also, was tun? Man kann Alternativen nehmen. Die können aber auch Sicherheitslücken haben. Oder bieten nicht die Funtkionen, die man braucht. ImageMagick immer auf dem aktuellen Stand (Sicherheitspatches!) zu halten, hilft sicher. Vielleicht das Tool nur in einer Sandbox ausführen, so dass code execution bugs keine Chance haben, viel Schaden anzurichten? Nur Bilder aus vertrauenswürdigen Quellen verarbeiten?
Auf jeden Fall: Vorsichtig sein. Schauen, was andere empfehlen. Und das gilt nicht nur für ImageMagick sondern auch für alle anderen tools, die unglaublich praktisch sind und mit einem riesigen Haufen komplexer Dateiformate umgehen können.
Trotz allen Sicherheitsbedenken ist ImageMagick eine tolle Sammlung von Werkzeugen. Mir hat es schonoft geholfen.