ImageMagick kann mehr, als nur fertige Bilder zu bearbeiten. Die freie Software erstellt sogar automatisiert und skriptgesteuert einfache Zeichnungen.
Obwohl man zum Zeichnen und Malen in der Regel ein richtiges Grafikprogramm verwendet, gibt es durchaus Situationen, in denen es gilt, regelmäßige Formen in einem Bild in fest definierten Abständen wiederholt zu zeichnen, wie beispielsweise hier gezeigt beim Erstellen der Silhouette einer fiktiven Stadt (Abbildung 1). Dafür braucht es kein kostspieliges Grafikprogramm mit ausgefeilten Makro-Sprachen: Das kostenlose und freie Softwarepaket ImageMagick und eine Kommandozeile genügen für diese Aufgabe.
Für umfangreichere Bildkompositionen sollte man sich allerdings von einer Skriptsprache wie der Bash unterstützen lassen, die mithilfe von Schleifen und anderen Kontrollstrukturen Bildinhalte wiederholt in die Grafik einfügt. ImageMagick findet sich in den Paketquellen der meisten Linux-Distributionen, lässt sich zur Installation aber auch aus dem Download-Bereich der Projektseite herunterladen [1].

Abbildung 1: Bild einer mit ImageMagick erstellten Skyline. Die Anzahl der Fenster und Stockwerke übergeben Sie als Parameter.
Malen mit Kommandos
Nach erfolgreicher Installation tippen Sie auf der Kommandozeile magick logo: logo.gif. Daraufhin legt ImageMagick im aktuellen Verzeichnis die Datei logo.gif an. Sie zeigt den in der oberen rechten Ecke von Abbildung 1 zu sehenden Zauberer, wie Sie durch Öffnen der Datei in einem geeigneten Bildbetrachter leicht überprüfen können. Bildnamen, die mit einem Doppelpunkt enden, stehen in ImageMagick für eingebaute Testbilder. Weitere Testbilder erhalten Sie mit den Optionen rose: und wizard: [2].
Den Beweis dafür, dass man mithilfe von ImageMagick auf der Kommandozeile zeichnen kann, liefert der Befehl aus Listing 1.
Listing 1
Rechteck
$ magick -size 500x300 \ xc:skyblue -fill red \ -draw 'roundrectangle \ 100,50,400,250,80,60' \ bild.png
Er legt mittels des Parameters -size zunächst die Bildgröße fest. Anschließend füllt xc:skyblue den Hintergrund des Bilds mit himmelblauer Farbe. xc: steht dabei historisch gesehen für “X Constant Image”, steht heute aber für Leinwand oder Canvas. Die Anweisung erwartet eine Farbbezeichnung aus dem Fundus des X-Window-Systems – dessen Farbnamen hat ImageMagick übernommen [3].
Möglich wäre auch die Angabe eines Farbverlaufs, etwa durch gradient:blue statt xc:skyblue. Der eingebaute Gradient Image Generator würde dann für Sie einen blauen Farbverlauf als Hintergrundbild erzeugen. Einen Eindruck der Möglichkeiten liefert die Dokumentation von ImageMagick. Im Detail geht die Anleitung zum Beispiel auf Plasma-Leinwände [4] und Farbverläufe [5] ein.
Hinter dem Parameter -fill steht die Definition der Zeichenfarbe für den nachfolgenden mit -draw eingeleiteten und in Hochkommas eingeschlossenen eigentlichen Zeichenbefehl. Als letzter Parameter folgt der Name der zu erstellenden Bilddatei.
Als Ergebnis erhalten Sie ein rotes, an den Ecken abgerundetes Rechteck auf hellblauem Hintergrund. Komplexere Zeichungen erstellen Sie durch das Aneinanderreihen mehrerer Zeichenbefehle (Listing 2, Zeile 1 bis 3).
Listing 2
Mehrere Elemente
$ magick -size 500x300 xc:skyblue -fill red -draw 'roundrectangle 100,150,400,225,55,10' \ -draw 'roundrectangle 200,100,350,180,50,10' -fill black -draw 'circle 150,225 180,225' \ -draw 'circle 350,225 380,225' auto.png $ magick auto.png -fill red -draw 'polygon 175,150 200,110 200,150' auto-bevel.png $ mogrify -fill red -draw 'polygon 175,150 200,110 200,150' auto.png
Drei-Schachtel-Prinzip
Das Ergebnis des ersten Aufrufs aus Listing 2 zeigt Abbildung 2: ein sehr stark vereinfachtes Symbol eines Autos mit Stufenheck nach dem Drei-Schachtel-Prinzip. Indem Sie den Zeichenbefehl aus Zeile 4 des Listings nachreichen, können Sie die Limousine noch ein wenig verschönern. Er schrägt die Fahrgastzelle im Frontbereich etwas ab.
Dabei dient die soeben erstellte Datei auto.png als Grundlage für die nachträgliche Abschrägung der Fahrgastzelle. Das Ergebnis schreibt das Kommando in die Datei auto-bevel.png. Möchten Sie das ständige Neuerstellen von Dateien vermeiden, verwenden Sie stattdessen das Kommando aus der letzten Zeile des Listings, das direkt die Datei auto.png modifiziert.
Obwohl beide Verfahren für die ersten Versuche beim Erlernen von ImageMagick zunächst durchaus Vorteile haben, wohnt ihnen doch ein entscheidender Nachteil inne: Sie arbeiten vergleichsweise langsam. Sie können sich sicher vorstellen, dass es sich kompliziert gestaltet, ein ganzes Hochhaus auf diese Weise zu zeichnen. Dazu müssten Sie etliche draw-Kommandos aneinanderreihen, schon für jedes einzelne Fenster wäre ein eigener Aufruf erforderlich. Darüber hinaus müssten Sie vorab die Position eines jeden Fensters manuell berechnen.
Schneller mit Skripten
Abhilfe schafft ein Skript, das die Bildgröße anhand der ihm übergebenen Angaben zur gewünschten Anzahl an Etagen und Fenstern pro Etage ermittelt. Es legt zusätzlich einen Farbverlauf für den Hintergrund fest und speichert das Bild zunächst ab. Anschließend berechnet es sämtliche Zeichenanweisungen für das eigentliche Gebäude sowie die Fenster und Türen und sammelt sie in einer XML-formatierten MSL-Datei. Das Kürzel MSL steht für Magick Scripting Language.
Abschließend verarbeitet das Skript mittels einer conjure-Anweisung die gesammelten Zeichenbefehle, was die Geschwindigkeit gegenüber einer schrittweisen Entwicklung des Bilds mittels einzelner mogrify-Anweisungen erheblich verbessert. Listing 3 zeigt eine MSL-Datei für ein kleines zweistöckiges Haus mit Fundament, fünf Fenstern und einer Haustür.
Listing 3
miniHaus.msl
<?xml version="1.0" encoding="UTF-8"?> <image> <read filename='miniHaus.png' /> <draw fill='sandybrown' primitive='rectangle 250, 1940, 810, 2500' /> <draw fill='snow4' primitive='rectangle 0, 2500, 1060, 3000' /> <draw fill='yellow' primitive='rectangle 270, 1970, 370, 2090' /> <draw fill='yellow' primitive='rectangle 690, 1970, 790, 2090' /> <draw fill='yellow' primitive='rectangle 440, 1970, 620, 2090' /> <draw fill='yellow' primitive='rectangle 270, 2250, 370, 2370' /> <draw fill='yellow' primitive='rectangle 690, 2250, 790, 2370' /> <draw fill='yellow' primitive='rectangle 440, 2250, 620, 2500' /> <write filename='miniHaus.png' /> </image>
Das diesem Workshop zugrunde liegende Shell-Skript baueHaus rufen Sie wie in Listing 4 gezeigt auf. Seinen Inhalt übernehmen Sie unverändert aus Listing 5. Der Einfachheit halber verzichtet das Skript auf eine umfangreiche Prüfung der übergebenen Parameter. Darüber hinaus kommen ausschließlich Positionsparameter zum Einsatz, bei denen die Aufrufreihenfolge in der Kommandozeile über die Zuordnung im Skript entscheidet. Möchten Sie das Skript verbessern, sollten Sie sich mit den Prüfmöglichkeiten der Shell auseinandersetzen sowie über den ergänzenden Einsatz von getopts im Skript nachdenken.
Listing 4
Beispiel-Syntax
$ ./baueHaus Datei Etagen FensterProEtage
Listing 5
baueHaus
#/bin/bash
if [ -z "$1" ]; then
echo "Bitte mindestens den Namen der Ausgabedatei ohne Dateiendung als Parameter angeben, optional noch die Anzahl der Etagen und der Fenster pro Etage."
exit
fi
zeilen=5
spalten=10
ox=250 # X-Offset des Hauses
oy=2500 # Y-Offset des Hauses
if [ $# -ge 3 ]; then
zeilen=`expr $2`
spalten=`expr $3`
if [ $# -ge 4 ]; then
ox=`expr $4`
fi
fi
rh=250 # Raumhoehe
fh=120 # Fensterhoehe
fb=100 # Fensterbreite
dh=30 # Deckenhoehe
fa=20 # Fensterabstand
ma=300 # Mittelabstand/breite Treppenhauserker
mslfile="$1.msl"
hausbreite=`expr $spalten \* \( $fa + $fb \) + $fa + $ma`
haushoehe=`expr $zeilen \* \( $rh + $dh \)`
t="$ox, `expr $oy - $haushoehe`, `expr $hausbreite + $ox`, $oy"
mitte=`expr $hausbreite / 2 + $ox`
mahalb=`expr $ma / 2`
mittelinks=`expr $mitte - $mahalb + \( 3 \* $fa \)`
mitterechts=`expr $mitte + $mahalb - \( 3 \* $fa \)`
magick -size "`expr $ox + $hausbreite + $ox`"x3000 gradient:#0000ff-#ffffff -draw "rectangle $t" $1.png
str="0, 2500, `expr $ox + $hausbreite + $ox`, 3000"
echo '<?xml version="1.0" encoding="UTF-8"?>' > $mslfile
echo '<image>' >> $mslfile
eingabefile="<read filename=\"$1.png\" />"
echo $eingabefile >> $mslfile
echo " <draw fill='sandybrown' primitive='rectangle $t' />" >> $mslfile
echo " <draw fill='snow4' primitive='rectangle $str' />" >> $mslfile
oben=`expr $oy - $haushoehe + $dh`
links=$ox
for ((i=0; i < zeilen; i++)) ; do
links=`expr $links + $fa`
for ((j=0; j < spalten; j++)) ; do
varInt=`expr $spalten / 2`
if [ $j -eq $varInt ]; then
links=`expr $links + $ma`
fi
t="$links, $oben, `expr $links + $fb`, `expr $oben + $fh`"
echo " <draw fill='yellow' primitive='rectangle $t' />" >> $mslfile
links=`expr $links + $fb + $fa`
done
if [ $i -ne `expr $zeilen - 1` ]; then
tm="$mittelinks, $oben, $mitterechts, `expr $oben + $fh`"
echo " <draw fill='yellow' primitive='rectangle $tm' />" >> $mslfile
else
tm="$mittelinks, $oben, $mitterechts, `expr $oben + $rh`"
echo " <draw fill='yellow' primitive='rectangle $tm' />" >> $mslfile
fi
links=$ox
oben=`expr $oben + $rh + $dh`
done
ausgabefile="<write filename=\"$1.png\" />"
echo $ausgabefile >> $mslfile
echo '</image>' >> $mslfile
conjure msl:$mslfile
Beim Aufruf des Skripts geben Sie den Dateinamen ohne Dateiendung an. Die Endungen .msl sowie .png ergänzt der Code automatisch. Lassen Sie die Option für die Etagenanzahl und die Anzahl an Fenstern pro Etage leer, dann nutzt das Skript vorgegebene Standardwerte. Den Dateinamen dagegen müssen Sie immer angeben, anderenfalls bricht das Programm ab. Die Anzahl an Etagen und Fenstern pro Etage müssen Sie immer gemeinsam anhängen, da das Skript die Parameter sonst nicht komplett angegeben wertet und dann beide durch Standardwerte ersetzt.
Haben Sie alle Angaben gemacht, dürfen Sie optional noch einen vierten Parameter für die Korrektur des Grenzabstands zum Nachbargrundstück angeben, falls Sie wie in Listing 6 gezeigt die Mustersiedlung aus Abbildung 1 nachbauen möchten. Die Tabelle “Kommandozeilenwerkzeuge des ImageMagick-Pakets” erläutert unter anderem die Bedeutung der Werkzeuge montage und composite.
Listing 6
Bau einer Skyline
$ ./baueHaus haus1 8 8 $ ./baueHaus haus2 4 10 0 $ ./baueHaus haus3 5 10 0 $ ./baueHaus haus4 1 8 250 $ magick montage haus1.png haus2.png haus3.png haus4.png -geometry +0 -tile x1 strasse.png $ magick composite logo: strasse.png -gravity NorthEast strasse-magick.png
|
Werkzeugname |
Funktion |
|---|---|
|
|
Standardwerkzeug des ImageMagick-Paketes. Es kann Dateiformate konvertieren und Bilder skalieren, weichzeichnen, beschneiden, entrauschen, dithern, drehen, spiegeln und vieles mehr. |
|
|
Gibt eine Beschreibung des Formats und der Charakteristika einer oder mehrerer Grafikdateien aus. |
|
|
Bietet dieselben Funktionen wie |
|
|
Überlappt zwei Bilder. |
|
|
Setzt mehrere Bilder zu einem zusammen. |
|
|
Zeigt die Unterschiede zwischen zwei Grafiken an (als Bericht einer mathematischen Analyse und visuell). |
|
|
Kopiert einzelne oder mehrere Pixel-Komponenten eines Bilds in ein anderes Format. Hauptsächlich für sehr große Bilddateien gedacht. |
|
|
Zeigt ein Bild oder eine Bildersequenz über einen X-Server an. |
|
|
Erstellt unter X11 Bildschirmfotos. Die Funktion sichert wahlweise den gesamten Bildschirmbereich, den Bereich eines Fensters oder ein definiertes Rechteck. |
|
|
Interpretiert Skripte in der Magick Scripting Language (MSL) und führt sie aus. |
Fazit
Wie Sie gesehen haben, mausert sich ImageMagick in Verbindung mit selbst geschriebenen Shell-Skripten zu einem sehr mächtigen Werkzeug, mit dem Sie nicht nur Bilder bearbeiten können, sondern bei Bedarf sogar automatisiert neue Grafiken erstellen. Es lohnt sich daher, sich mit diesem Thema einmal zu beschäftigen. (cla)
Der Autor
Ralf Kirschner arbeitet als Visual-Basic-Programmierer in einem Software- und Systemhaus. Der ausgebildete Systemadministrator erteilt auch freiberuflich Computerschulungen.
Infos
- ImageMagick: https://imagemagick.org/index.php
- Eingebaute Testbilder, Füllmuster etc.: https://imagemagick.org/script/formats.php
- X-Window-Farbnamen: https://imagemagick.org/script/color.php
- Plasma Gradients: https://legacy.imagemagick.org/Usage/canvas/#plasma
- Canvas-Erstellung: https://legacy.imagemagick.org/Usage/canvas/#gradient
- Beispielskripte: http://www.cssenior.de/BegleitdateienSkylinebauImageMagick.zip






