Aus Linux-Magazin 03/2019

Ein Python-Skript übernimmt die händische Bildoptimierung in Gimp

© bennyartist, 123RF

Statt nacheinander immer die gleichen Bildverarbeitungsschritte in Gimp abzuarbeiten, lässt Mike Schilli diese Aufgabe ein Python-Skript über einen handgeschriebenen Menü-Eintrag erledigen.

Selbst Handykameras zeichnen Bilder in Riesenformaten auf, die sich kaum für den Blog oder zum Versenden durch enge Datenleitungen eignen. Also skaliere ich Photos runter auf 2000 mal 1000 Pixel, schärfe vielleicht noch nach oder führe den Weißabgleich durch. Der Bildbearbeiter Gimp führt dies klaglos aus, allerdings wäre es schön, wenn er die immer gleichen Schritte statt von Hand automatisch ausführen würde.

In einem Rutsch

Zum Glück lassen sich selbst geschriebene Python-Skripte einfach in Gimp integrieren. Die Ubuntu-Installation des Pakets »gimp« enthält bereits alle Zutaten für hausgemachte Kommandos. Listing 1 initialisiert ein handgeschriebenes Plugin zum Skalieren und Schärfen eines Fotos. Ins Verzeichnis »~/.gimp-2.8/plug-ins/« überspielt und ausführbar gemacht, findet Gimp die Datei beim Hochfahren und fügt den Menü-Eintrag unter »Filters | MyStuff | Sharpen and Scale« ein (Abbildung 1). Letzteren zeigen Gimps Kontext- und Dropdown-Menü an.

Listing 1

sharpscaleplugin.py

01 #!/usr/bin/env python
02 from gimpfu import *
03 from sharpscale import sharp_scale
04
05 register(
06   "python-fu-sharp-scale",
07   "Sharpen and scale",
08   "First sharpens, then scales",
09   "Mike Schilli",
10   "Mike Schilli",
11   "2019",
12   "_Sharpen and Scale",
13   "RGB",
14   [
15     (PF_IMAGE,
16         "image", "Input image", None),
17     (PF_DRAWABLE,
18         "drawable", "Input drawable", None)
19   ],
20   [],
21   sharp_scale,
22   menu="<Image>/Filters/MyStuff"
23 )
24
25 main()

Die Programmlogik zur Bildverarbeitung ruft Listing 1 in Zeile 21 mit »sharp_scale()« auf. Diese Funktion hat es vorher in Zeile 3 per Importkommando aus der Datei »sharpscale.py« (Listing 2) importiert. Letztere findet Gimp auch im Plugin-Verzeichnis, wohin der User sie installiert hat. Anders als zuvor sind keine Ausführungsrechte nötig, da Listing 1 sie nur als Bibliothek nutzt.

Listing 2

sharpscale.py

01 from gimpfu import *
02
03 SIZE_MAX=2000
04 SHARPEN=10
05
06 def sharp_scale(img, layer):
07   w, h = scale_coords(
08     img.width, img.height)
09
10   pdb.gimp_image_undo_group_start(img)
11
12   pdb.gimp_progress_init(
13     "Scaling Image to %dx%d ..." % (w, h),
14     None)
15
16   pdb.gimp_context_set_interpolation(
17     INTERPOLATION_LANCZOS)
18
19   pdb.gimp_image_scale(img, int(w), int(h))
20
21   pdb.gimp_progress_init(
22     "Sharpening Image with %d ..." %
23       SHARPEN, None)
24   pdb.plug_in_sharpen(img, layer, SHARPEN)
25
26   pdb.gimp_levels_stretch(layer)
27
28   pdb.gimp_image_undo_group_end(img)
29
30 def scale_coords(w,h):
31   if max(w,h) < SIZE_MAX:
32     return w, h
33
34   if w<=h:
35     scale=SIZE_MAX/float(h)
36   else:
37     scale=SIZE_MAX/float(w)
38
39   return int(w*scale), int(h*scale)

Gimp-spezifische Python-Konstrukte wie die Funktion »register()« zum Einbinden des Plugin oder Konstanten wie »PF_IMAGE« holt Listing 1 in Zeile 2 aus dem Modul »gimpfu«, das Skripte in Gimps Plugin-Verzeichnis ohne weiteres Zutun finden. Als Parameter für den Aufruf der Plugin-Funktion definiert der Array ab Zeile 14 in Listing 1 einmal ein Image im Gimp-internen Format »PF_IMAGE« sowie als Drawable den obersten Layer, den später die Funktion zum Nachschärfen benötigt.

Neues Menü

Klickt der User auf den neuen Menüpunkt in Abbildung 1, springt das Plugin-Framework die Funktion »sharp_scale()« ab Zeile 6 in Listing 2 an und übergibt ihr den Descriptor des angezeigten Bildes sowie eine Referenz auf das Drawable. Die Ausmaße des verkleinerten Bildes errechnet die Funktion »scale_coords()« ab Zeile 30. Sie nimmt die aktuelle Breite und Höhe des Bildes aus Zeile 8 entgegen und bestimmt, ob es im Quer- oder Hochformat vorliegt.

Abbildung 1: Der per Python-Skript in Gimp eingerichtete Men&uuml;-Eintrag zum Skalieren und Sch&auml;rfen.

Abbildung 1: Der per Python-Skript in Gimp eingerichtete Menü-Eintrag zum Skalieren und Schärfen.

Den Skalierungsfaktor »scale« errechnet sie, indem sie die Länge der längste Seite durch die in der Konstanten »SIZE_MAX« vorliegende Maximalgröße teilt. Die Dimensionen des skalierten Bildes ergeben sich durch Multiplikation von Breite und Höhe des ursprünglichen Bildes mit dem Skalierungsfaktor in Zeile 39.

Da sich das Skalieren bei großen Bildern hinziehen kann und der User nach seinem Mausklick eine Rückmeldung erwartet, werfen die Zeilen 12 bis 14 mit »gimp_progress_init()« noch eine Statusmeldung aus, die Gimp als Progressbar anzeigt (Abbildung 2).

Abbildung 2: Dank &raquo;gimp_progress_init()&laquo; zeigt der Verkleinerungsprozess den Fortschritt unterhalb des Bildes an.

Abbildung 2: Dank »gimp_progress_init()« zeigt der Verkleinerungsprozess den Fortschritt unterhalb des Bildes an.

Beim Stauchen des Bildes muss Gimp mehrere Pixel in einem vereinen, was eine Glättung erfordert, damit das Bild hinterher noch natürlich aussieht. Zeile 17 stellt deswegen für die Interpolationsfunktion das so genannte Lanczos Resampling [2] ein.

Gut dokumentiert

Die Parameterwerte für den Aufruf interner Funktionen dokumentiert Gimp direkt im Programm in der Dialogbox, die unter dem Menüpunkt »Help | Procedure Browser« erscheint (Abbildung 3). Dort sucht der Entwickler nach einem Stichwort wie »scale« oder »sharpen« und findet nach etwas Herumprobieren meist die richtige interne Funktion und ihre Parameter. Geht etwas schief, wenn etwa das Plugin-Skript auf einen Fehler läuft und abbricht, schreibt Gimp eine Fehlermeldung auf die Konsole. Es empfiehlt sich also, Gimp während der Debug-Phase von der Kommandozeile zu starten, damit die Meldungen im Terminal Rückschlüsse auf Probleme erlauben. Nach Änderungen am Python-Code der Plugins ist Gimp neu zu starten, damit die Änderungen garantiert greifen.

Abbildung 3: Der Procedure-Browser enth&uuml;llt die Parameter g&auml;ngiger Gimp-Funktionen.

Abbildung 3: Der Procedure-Browser enthüllt die Parameter gängiger Gimp-Funktionen.

Zum Nachschärfen nimmt sich die Funktion »plug_in_sharpen()« ab Zeile 24 des aktuellen Bildes an. Den gewünschten Schärfewert definiert die Konstante »SHARPEN« in Zeile 4 mit dem Wert »10«, und Zeile 24 gibt ihn an das Sharpen-Plugin (ein Gimp bereits beigepacktes Standard-Plugin) weiter. Die Funktion benötigt laut Manual neben dem Gimp-Image auch dessen Drawable, das, wie oben erwähnt, die Plugin-Registrierung dem Aufruf von »sharp_scale()« von Anfang an mitgegeben hat.

Farbe bekennen

Als dritte Korrektur von Rohbildern gleiche ich oft die White-Balance ab. Schöpft ein digitales Foto nicht für jeden der drei Kanäle (Rot, Grün, Blau) die ganze Bandbreite der möglichen Pixelwerte von 0 bis 255 aus (Abbildung 4), wirken Bilder oft wenig lebendig und matt.

Abbildung 4: Vor dem Wei&szlig;abgleich zeigt das Histogramm eng verteilte Werte und ein mattes Bild.

Abbildung 4: Vor dem Weißabgleich zeigt das Histogramm eng verteilte Werte und ein mattes Bild.

Wer knalligere Farben und höheren Kontrast bevorzugt, kann in Gimps Menü-Eintrag »Colors | Auto | White Balance« ein recht brauchbares Tool abfeuern, das die Pixelwerte der drei Kanäle so anpasst, dass sich deren Verteilung im Histogramm auf die gesamte Intensitätsbandbreite erstreckt. Das sieht nicht immer gut aus, verleiht aber manchmal eher langweiligen Bildern den notwendigen Pep (Abbildung 5).

Abbildung 5: Der Wei&szlig;abgleich zieht das Histogramm in die Breite und das Bild wirkt lebendiger.

Abbildung 5: Der Weißabgleich zieht das Histogramm in die Breite und das Bild wirkt lebendiger.

Allerdings verlief meine Suche nach der zugehörigen Gimp-Funktion im Procedure- und auch im Plugin-Browser erst einmal erfolglos. Doch zum Glück ist Gimps Sourcecode auf Github ja für jedermann einsehbar (Abbildung 6), und eine kurze Suche nach dem String »Automatic white balance« ergab, dass die zugehörige Gimp-Prozedur »drawable_levels_stretch()« heißt.

Abbildung 6: Ein Blick in den Gimp-Sourcecode auf Github offenbart, dass die gesuchte Funktion f&uuml;r den Wei&szlig;abgleich &raquo;drawable_levels_stretch&laquo; hei&szlig;t.

Abbildung 6: Ein Blick in den Gimp-Sourcecode auf Github offenbart, dass die gesuchte Funktion für den Weißabgleich »drawable_levels_stretch« heißt.

Diese ist wiederum im Procedure-Browser dokumentiert und nimmt als Parameter nur das Drawable des Bildes entgegen. Flugs war dann der Aufruf in Zeile 26 von Listing 2 eingebaut und damit Teil des Bildverarbeitungsprozesses.

Ein Schritt vor und zurück

Die drei Aktionen zum Skalieren, Schärfen und die Farbkorrektur des Bildes behandelt Gimp von Natur aus als drei getrennte Einheiten. Überlegt es sich der User hinterher anders und klickt den »Undo«-Menü-Eintrag an, müsste er dies dreimal hintereinander tun, was nervt, denn schließlich hat er mit seinem Mausklick eigentlich nur eine kombinierte Aktion eingeleitet. Abhilfe schaffen der Aufruf von »gimp_image_undo_group_start()« in Zeile 10 sowie das korrespondierende »…_end()« in Zeile 28.

Beide definieren die dazwischenliegenden Aktionen als eine Undo-Einheit, sodass Gimp sie nur als Ganzes zurück- oder auch wieder vorrollt. Abbildung 7 zeigt, dass selbst Gimps »Edit«-Menü nun als letzte Aktion nicht mehr nur den (zuletzt gelaufenen) Weißabgleich anzeigt, sondern »Sharpen and Scale«, also den Namen der kombinierten Aktion für die ganze Enchilada in einem Rutsch.

Abbildung 7: Dank &raquo;undo_group_start()&laquo; und &raquo;...end()&laquo; kann Gimp die Aktionen in einem Rutsch zur&uuml;ckfahren.

Abbildung 7: Dank »undo_group_start()« und »…end()« kann Gimp die Aktionen in einem Rutsch zurückfahren.

Die Routinen haben gezeigt, dass Gimps Python-API Zugriff auf alle internen Funktionen hat. Es ist leicht, Arbeitsabläufe aus vielen kleinen Schritten zu bündeln, in ein Menü einzuhängen und in einem Aufwasch ablaufen zu lassen. Das spart Zeit und eliminiert Fehler bei der Bedienung.

Online PLUS

Im Screencast demonstriert Michael Schilli das Beispiel: https://www.linux-magazin.de/videos/

Der Autor

Michael Schilli arbeitet als Software-Engineer in der San Francisco Bay Area in Kalifornien. In seiner seit 1997 laufenden Kolumne forscht er jeden Monat nach praktischen Anwendungen verschiedener Programmiersprachen. Unter mailto:mschilli@perlmeister.com beantwortet er gerne Fragen.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 4 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben