Ulrichs Werkbank

Praxistipp: Verkleinern von Bildern

14. Januar 2018
von Ulrich Hilger

 

Digitalbilder müssen in einer möglichst hohen Auflösung vorliegen, damit das maximale Maß an Informationen bewahrt wird, also alle Bilddetails, Farben und Schattierungen. Für viele Verwendungen ist die maximale Auflösung hingegen nicht nötig, es genügt eine verkleinerte Fassung beispielsweise als komprimierte Bilddatei im PNG- oder JPEG-Format.

Viele Programme zum Umgang mit Bildern enthalten Funktionen zur Verkleinerung von Bildern. Für eine größere Menge von Bildern auf einmal ist es aber umständlich, mit Hilfe eines Bildbearbeitungsprogrammes jedes Bild von Hand einzeln nacheinander zu verkleinern. Ein Automatismus ist wünschenswert und einige Programme haben auch solche Möglichkeiten, zum Beispiel durch Skript-Fähigkeiten oder Programmschnittstellen.

Allerdings sind solche Automatisierungsmöglichkeiten an das jeweilige Programm gebunden. Eine automatisierte Funktion zum Verkleinern für größere Mengen von Bildern sollte möglichst eigenständig funktionieren und in möglichst vielen verschiedenen Arten verwendbar sein. Dieser Praxistipp stellt deshalb eine universell verwendbare Lösung auf der Grundlage von Java-Code vor. 

Übersicht

Allgemeine Beschreibung
Annahmen
Einrichten der Lösung
Verkleinern von Bildern
Vorteile
Alternativen
Fazit

 

Allgemeine Beschreibung

Das Skript zum Verkleinern von Bildern liest Bilder im JPEG-Format aus einem Eingangsordner und wandelt sie in kleinere Bilder um. Deren verkleinerte Version schreibt das Skript in einen Ausgangsordner. Eingangs- und Ausgangsverzeichnis, gewünschte Verkleinerung und Qualität sind als Parameter frei wählbar.

Das Skript zum Verkleinern von Bildern wird zusammen mit einem Skript zum vereinfachten Aufruf in einer Ablaufumgebung für Docker hinterlegt, wie sie beispielsweise im Artikel Docker auf Core OS und VirtualBox beschrieben ist.

Zum Verkleinern einer Gruppe von Bildern genügt anschließend ein einzelnes Kommando.

Annahmen

Für diesen Tipp wird davon ausgegangen, dass eine per SSH erreichbare Maschine names zielrechner besteht, die eine virtuelle Maschine namens CoreOS-Groovy enthält. Für die virtuelle Maschine wird angenommen, dass sie angelegt wurde, wie es der zuvor erwähnte Artikel beschreibt. Ferner ist die Annahme, dass derzielrechner einen Benutzer namens ulrich kennt.

Einrichten der Lösung

Die folgenden Schritte müssen nur einmal ausgeführt werden. Mit ihnen wird auf einem zentralen Rechner eine wiederverwendbare Funktion zum Verkleinern von Bildern eingerichtet.

  1. Die Skripte aus dem Repository auf den lokalen Rechner herunterladen und entpacken
  2. Eine Kommandozeile starten und eine Verbindung zur Zielmaschine öffnen
    ssh -l ulrich zielrechner
  3. Eine Portweiterleitung für die virtuelle Maschine anlegen
    VBoxManage modifyvm "CoreOS-Groovy" --natpf1 "ssh,tcp,,3022,,22"
  4. Die virtuelle Maschine starten
    VBoxManage startvm "CoreOS-Groovy" --type headless
  5. Eine SSH-Verbindung zur virtuellen Maschine öffnen
    ssh -p 3022 -l ulrich zielrechner
  6. Im Arbeitsverzeichnis der virtuellen Maschine die Ordner in und out anlegen
    mkdir in
    mkdir out
  7. Ein zweite Kommandozeile öffnen und die Skripte kleiner.sh und bilder.groovy vom lokalen Rechner ins Arbeitsverzeichnis der virtuellen Maschine kopieren
    scp -P 3022 kleiner.sh ulrich@zielrechner:.
    scp -P 3022 bilder.groovy ulrich@zielrechner:.
  8. Die zweite Kommandozeile schließen
    exit
  9. Die virtuelle Maschine beenden
    sudo shutdown -P now
  10. Die Verbindung zur Zielmaschine schließen
    exit
  11. Die Kommandozeile schließen
    exit

Portweiterleitung

Im Beispiel oben wird die virtuelle Maschine zur Verkleinerung von Bildern von einer Maschine namens zielrechner bereitgestellt. Damit bei der Kommunikation via SSH die Kommandos an die virtuelle Maschine nicht mit denen an den zielrechner vermischt werden, wird für die virtuelle Maschine eine Portweiterleitung eingerichtet. Anfragen an die virtuelle Maschine werden so über Port 3022 entgegengenommen und geraten nicht in Konflikt mit Anfragen an den zielrechner, die standardmäßig über Port 22 laufen.

Dockerfile

Die volle Stärke entfaltet Docker mit der Verwendung eines Dockerfiles denn es automatisiert wesentliche Teile des obigen Ablaufs. Grob gesagt werden dazu die beiden Skripte zusammen mit einem Dockerfile in ein Archiv gepackt. Dann reicht anstelle einiger der Schritte oben ein einfaches docker build Kommando. In diesem Beitrag wurde auf diese Vorgehensweise verzeichtet, weil dies die für eine Installation erforderlichen Schritte verschleiert hätte.

Wie eine Installation wie die obige mit einem Dockerfile automatisiert wird, ist insofern eher etwas für einen weiteren Praxistipp.

Verkleinern von Bildern 

Ist die Einrichtung wie oben erfolgt genügen für die Verkleinerung von Bildern die folgenden Schritte. Annahme für das Beispiel ist, dass die zu verkleinernden Bilder auf der lokalen Maschine im Ordner work/bilder/gross des aktuellen Arbeitsverzeichnisses liegen und dass es dort einen Ordner work/bilder/klein gibt.

  1. Eine Kommandozeile staten und eine Verbindung zur Zielmaschine öffnen
    ssh -l ulrich zielrechner
  2. Die virtuelle Maschine starten
    VBoxManage startvm "CoreOS-Groovy" --type headless
  3. Ein zweite Kommandozeile offnen und die Bilder vom lokalen Rechner zur virtuellen Maschine kopieren
    scp -P 3022 work/bilder/gross/* ulrich@zielrechner:./in
  4. Das Kommando zum Verkleinern ausführen
    ./kleiner.sh 1920 0.75 /scripts/in /scripts/out
  5. Die verkleinerten Bilder aus dem Verzeichnis out holen
    scp -P 3022 ulrich@zielrechner:./out/* work/bilder/klein
  6. Die zweite Kommandozeile schließen
    exit
  7. Den Ein- und Ausgangsordner der virtuellen Maschine leeren
    rm in/*
    rm out/*
  8. Die virtuelle Maschine beenden
    sudo shutdown -P now
  9. Die Verbindung zur Zielmaschine schließen
    exit
  10. Die Kommandozeile schließen
    exit

Diese Schritte lassen sich abermals mit einem Skript automatisieren. Zuguterletzt werden einfach da, wo gerade Bilder zum Verkleinern liegen, diese in einen Bearbeitungsordner kopiert, ein Ausgangsordner für das Ergebnis angelegt und ein Skript ausgeführt, das die obigen Schritte auf diese Ordner anwendet.

Bei der ersten Ausführung lädt Docker automatisch die passenden Ablaufumgebungen für Java und Groovy ins lokale Docker-Repository der virtuellen Maschine. Die erste Ausführung dauert deshalb länger.  

Vorteile

Auf der Maschine, die zum Ablauf der Funktion verwendet wird, muss nur VirtualBox installiert sein und nicht weiter ins System eingegriffen werden. Alle Konfigurationen sind deklarativ und Teil einer virtuellen Maschine, was die Abhängigkeit von einer bestimmten Plattform aufhebt und zudem eine wiederverwendbare und auf die jeweilige Lösung abgestimmte Ablaufumgebung schafft.

Die Verkleinerungsfunktion wird mit Java ausgeführt und benötigt über Java hinaus keine anderen Hilfsmittel wie etwa besondere Bildbearbeitungsprogramme.

Der Kern der Lösung besteht aus dem Kopieren der Bilder an einen Beabreitungsort sowie das Kommando zum Verkleinern (kleiner.sh usw.). Es muss keine Anwendung installiert werden bzw. wird alles erforderliche von Docker zu Beginn selbsttätig geladen und bleibt im Docker-Repository der virtuellen Maschine wiederverwendbar hinterlegt. Werden zwischenzeitlich Teile dieser Ablaufumgebung, also Java oder Groovy aktualisiert, lädt Docker die aktuellen Fassungen bei der nächsten Ausführung abermals selbsttätig.

Die Einrichtung innerhalb einer virtuellen Maschine ermöglicht es, diese sehr einfach zwischen verschiedenen Maschinen zu transportieren. Die Nutzung der virtuellen Maschine und mithin die Verkleinerung von Bildern gelingt dabei komplett isoliert und unabhängig vom System der jeweiligen 'Gastgeber'-Maschine.

Alternativen

Durch die Verwendung von Java, VirtualBox und Docker lassen sich viele unterschiedliche andere Varianten denken, in denen die hier vorgestellte Lösung eingesetzt werden kann. Nachfolgend ein paar Ideen, die die Flexibilität des Ansatzes zeigen sollen.

Java-Code anders einbinden

Da es sich beim Code des Groovy-Skripts um normales Java handelt ist dieser gleichermaßen für den Einsatz in einer andern Anwendung verwendbar. So kann er in der selben Weise in ein Programm eingebaut werden und für denselben Zweck zum Beispiel als Teil einer Serveranwendung laufen.

Groovy lokal installieren

Anstelle der Ausführung innerhalb von Docker kann auch einfach Groovy auf einem Rechner installiert und das Groovy-Skript ausgeführt werden. Damit ist allerdings ein Eingriff in das System eines Rechners erforderlich und die Lösung zunächst an diesen Rechner gebunden. Auf einem anderen Rechner könnte sie nur laufen, wenn dort auch Groovy installiert würde.

Virtuelle Maschine auf lokalem Rechner

Die virtuelle Maschine kann ebensogut auf dem lokalen Rechner betrieben werden, dann geht der Schritt des Kopierens der Bilder in die virtuelle Maschine hinein und aus der virtuellen Maschine heraus nicht über eine vielleicht langsame Netzstrecke. Damit ist allerdings die Lösung zunächst an diesen Rechner gebunden und kann nicht ohne weiteres an zentraler Stelle von verschiedenen Rechnern aus benutzt werden.

Docker auf lokaler Maschine

Eine weitere Variante ist, auf der betreffenden Maschine selbst Docker zu installieren. Dann kann das Skript zum Verkleinern von Bildern direkt auf ein Verzeichnis der lokalen Maschine ausgeführt werden. Die Schritte zum Kopieren der Bilder, Anmelden am Zielrechner, Starten und Stoppen der virtuellen Maschine können dann entfallen. Allerdings hat man so auch eine deutlich engere Koppelung an diese Maschine. Bei einem einfachen Skript wie dem hier vorgestellten fällt das nicht ins Gewicht. Für eine komplexere Lösung empfiehlt sich hingegen die hier beschriebene Virtualisierung.

ImageMagick anstelle von Java-Code

Anstelle von Java und Groovy kann z.B. auch ImageMagick verwendet werden, das ist Geschmackssache. Die Vorgehensweise mit VirtualBox und Docker bleibt die gleiche, nur das Kommando zur Verkleinerung lautet mit ImageMagick dann anders. Auch kann diese Variante nicht ohne weiteres in andere Programme eingebaut werden und würde beim Einbau die Installation von ImageMagick zusätzlich zum eigenen Programm erfordern.

Fazit

Java ist eine universelle, wiederverwendbare Form, Lösungen für Aufgaben zu formulieren, die von einer Vielzahl von Geräten ausgeführt werden können. Die Formulierung in Form von Java-Code erhöht die Wiederverwendbarkeit für die Nutzung der Lösung in einem anderen Kontext wie z.B. eingebettet in eine Webanwendung.

Groovy ist eine praktische Ablaufumgebung für Java-Code, der eigenständig und gezielt eine bestimmte Aufgabe lösen soll.

VirtualBox und Docker sind ideale Werkzeuge um Aufgaben entkoppelt von der jeweiligen Maschine auszuführen. 

Mit den Mitteln von VirtualBox und Docker lassen sich vorhandene Lösungen automatisiert auf eine Plattform bringen und unabhängig von der Zielplattform ausführen. Die Bedienung ist jeweils auf wenige Handgriffe verringert und einmal zum Laufen gebracht mit wenigen Schritten auf anderen Plattformen wiederverwendbar. 

Das hier beschriebene Vorgehen zur Virtualisierung und Containerisierung kann ebenso für andere Aufgaben verwendet werden. Es ist eine Musterlösung für die Ausführung beliebiger Aufgaben mit einer virtualisierten Ablaufumgebung und nicht auf das hier vorgestellte Beispiel zur Verkleinerung von Bildern beschränkt.

 

 

Dieser Artikel ist hier in einer anders formatierten Fassung zu lesen.