Gimp-Scripts schreiben

Aus LinuxUser 02/2005

Gimp-Scripts schreiben

© photocase.de

Programmiertes Malen

Gimp ist schon seit langem das beste Programm für Bildbearbeitung unter Linux . Es lässt sich nicht nur mit der Maus bedienen, sondern auch mit eigenen Skripts automatisieren. Die Sprache Python bietet sich dabei als Alternative zum eingebauten Lisp-Dialekt an.

Der Bildbearbeiter Gimp kennt eine Menge nützlicher Funktionen. Sich ständig durch die komplizierte Menüstruktur zu klicken, wird bei einer großen Zahl an Bildern mühsam. Praktischerweise bietet Gimp eine eingebaute Programmierschnittstelle für eigene Skripts, die häufige Aufgaben automatisieren. Die verwendete Programmiersprache Scheme [1] ist allerdings nicht jedermanns Sache, denn ihre von Klammern geprägte Syntax (siehe Glossar S. 30) ist gewöhnungsbedürftig.

Deshalb haben die Fans anderer Skriptsprachen für Alternativen gesorgt. Sehr weit entwickelt ist die Perl-Schnittstelle Gimp-Perl. Unter anderem kennt sie einen Server-Modus, in dem Gimp ohne grafische Oberfläche Skripts abarbeitet.

Verbreitetes Python

Der Perl-Modus fehlt allerdings bei den Gimp-Versionen der meisten Distributionen. Dagegen hat sich Gimp-Python als Scheme-Alternative etabliert, die in fast allen Linux-Varianten zur Verfügung steht. Nur Suse-Benutzer haben Pech, denn bei ihrem System fehlt Gimp-Python, siehe Kasten “Selbst kompilieren”.

Selbst kompilieren

Wer Gimp selbst übersetzten möchte, findet den Quellcode der aktuellen Version 2.2 auf der Heft-CD. Nach dem Entpacken führen Sie das Konfigurationsskript mit dem für Python nötigen Parameter aus: ./configure --enable-python.. Um Konflikte zu vermeiden, sollten Sie installierte Gimp-Pakete entfernen, bevor Sie mit make install eine frische Version installieren.

Fedora-Benutzer können gleich loslegen, Debian- und Ubuntu-User müssen eventuell noch das Paket gimp-python nachinstallieren.

Datenbank mit Plugin-Funktionen

Die für das Python-Plugin relevanten Einträge finden Sie im Hauptmenü unter Xtns | Python-Fu. Mit dem dort befindlichen Punkt Test | Sphere testen Sie die Installation: Haben Sie den folgenden Dialog mit dem Button OK bestätigt, sollte eine rote Kugel mit Schatten erscheinen.

Auftretende Fehler gibt Gimp in dem Terminalfenster aus, in dem es gestartet wurde. Beim Start über ein grafisches Menü öffnen Sie zur Fehlerdiagnose stattdessen das entsprechende Gimp-Fenster über Datei | Dialoge | Fehlerkonsole. Die Konsole zeigt allerdings nicht alle auftretenden Probleme an. Deshalb sollten Gimp-Skripter das Programm von einem Terminalfenster aus starten.

Als wichtigstes Tool für angehende Gimp-Programmierer fungiert der Browser für die so genannte Procedural Database, kurz PDB (Abbildung 1), zu finden im Hauptmenü unter Xtns | Python-Fu | PDB-Browser. Er listet Funktionen, die Skript-Programmierern in Gimp zur Verfügung stehen. Zum Beispiel lädt die Funktion file_jpg_load eine JPG-Datei. Direkt ausführen lassen sich solche Methoden in der Python-Console (Xtns | Python-Fu | Console).

Abbildung 1: Der in Gimp eingebaute Browser für Skripting-Funktionen. Das linke untere Feld dient zur Suche.

Abbildung 1: Der in Gimp eingebaute Browser für Skripting-Funktionen. Das linke untere Feld dient zur Suche.

Der Browser ist die maßgebliche Informationsquelle für die in der jeweiligen Gimp-Version eingebauten Funktionen. Im Netz kursierende Tutorials und Referenzen befinden sich leider oft nicht auf dem aktuellen Stand. Die Suchfunktion hilft, die angezeigten Funktionen auf das eigene Interessenfeld zu begrenzen. Suchen Sie zum Beispiel nach layer, zeigt der Browser alle Funktionen mit passendem Namen. Klicken Sie im linken Feld eine Funktion an, zeigt der PDB-Browser rechts die zugehörigen Infos. Wichtig sind neben der Funktionalität selbst die Parameter (In) und der Rückgabewert (Out).

Plugins registrieren

Die Grundstruktur eines Python-Plugins ist einfach: ein Aufruf von register, um Gimp das neue Plugin bekannt zu machen, plus eine oder mehrere Funktionen, die die eigentliche Arbeit verrichten. Die soll fürs erste Beispiel nur darin bestehen, ein Dialogfenster anzuzeigen. Eine Suche im PDB-Browser führt zur Funktion gimp_message, mit dem anzuzeigenden Text als einzigem Parameter.

Die Methode register erwartet elf Parameter in dieser Reihenfolge: Name der Plugin-Funktion, Beschreibung, Hilfetext, Autor, Copyright, Datum, Menüpfad, zulässige Bildformate, Plugin-Parameter, Speicher für den Rückgabewert, Arbeitsfunktion. Nach der Registrierung folgt der obligatorische Aufruf der Funktion main().

Der Name der Plugin-Funktion lautet im Beispiel python_fu_simple. Unter diesem Namen lässt sie sich nach der Registrierung (auch von anderen Plugins aus) aufrufen. Die folgenden vier Parameter dürften keine Schwierigkeiten bereiten, denn es handelt sich nur um informative Strings. Wichtiger ist der nun folgende Menüpfad, den es grundsätzlich in zwei Varianten gibt: im Gimp-Hauptmenü oder im Kontextmenü jedes Bilds (rechte Maustaste). Fürs Hauptmenü lautet der erste Teil des Menü-Strings <Toolbox>, beim Bildmenü passenderweise <Image>. Danach folgen die durch Schrägstriche getrennten Menüs, die Gimp nach Bedarf aufbaut: <Image>/Python/Simple.

Der nächste Parameter legt fest, mit welchen Bildtypen (nicht Formaten) das Skript umgehen kann, also Farbbilder mit (RGBA) beziehungsweise ohne (RGB) Alpha-Kanal oder Graustufenbilder (GRAY). Kümmert sich das Plugin darum nicht, darf hier auch ein Stern (*) stehen.

Schließlich folgen die Ein- und Ausgabeparameter und der Name der Arbeitsfunktion. Ein vollständiges Minimalbeispiel zeigt Listing 1.

Listing 1

Einfaches Gimp-Skript

#!/usr/bin/python
from gimpfu import *
def python_simple(img, drawable):
   gimp.message("Einfaches Beispiel")
register(
   "python_fu_simple",
   "Zeigt einen Dialog an",
   "Hilfe: Zeigt einen Dialog",
   "Oliver Frommel",
   "LinuxUser",
   "2005",
   "<Image>/Python/Simple",
   "*",
   [],
   [],
   python_simple)
main()

Die Plugin-Funktion heißt hier python_fu_simple (Zeile 9), die Arbeitsfunktion python_simple. Die Arbeitsfunktion besitzt immer die beiden Parameter img und drawable (Zeile 5), die Gimp automatisch übergibt – die Eingabeparameterliste in Zeile 17 ist ja leer. Zeile 3 zeigt, wie man das Gimp-Modul in Python lädt (siehe dazu auch den Artikel auf S.30).

Speichern Sie das Listing unter dem Namen simple.py und legen Sie es im Verzeichnis ~/.gimp/plug-ins ab. Eventuell heißt das entsprechende Verzeichnis auch .gimp-2.0 oder ähnlich. Geben Sie dem Skript mit chmod +x Ausführungsrechte und starten Sie Gimp. Wenn sie nun ein neues Bild anlegen (Datei | Neu) finden Sie das Plugin in dessen Kontextmenü unter Python | Simple.

Gimp baut Dialoge

Das Minimalbeispiel ist zugegebenermaßen nicht sehr unterhaltsam. Deshalb soll ein sinnvolles Beispiel weitere wichtige Aspekte von Gimp-Python demonstrieren. Das Plugin soll ein Bild mit einer so genannte Vignette versehen, einem Schatten, der Unwichtiges abdunkelt und dafür das Wesentliche hervorhebt. Das Beispiel demonstriert Plugin-Parameter und Gimp-Funktionen, die mit Auswahlmasken arbeiten.

Die zugrunde liegende Idee ist einfach: Das Skript wählt mit der entsprechenden Funktion einen elliptischen Bereich aus, der so groß ist wie das ganze Bild. Dann invertiert es die Auswahl und füllt den Bereich mit dem Füllwerkzeug. Passende Transparenzwerte und ein weicher Verlauf der Auswahl gestalten den Übergang zwischen Vignette und Bild so sanft, wie es für den gewünschten Effekt nötig ist.

Die Registrierung des Plugins entspricht im wesentlichen dem Minimalbeispiel. Allerdings kommen dieses Mal die Eingabeparameter ins Spiel, für die Gimp automatisch einen passenden Dialog erzeugt. Innerhalb der eckigen Klammern erhält jeder Parameter vier Werte, die wiederum in runden Klammern stehen. Der erste gibt den Parametertyp an, der zweite ist ein String mit dem Variablennamen. Dieser steht dann im eigenen Skript zur Verfügung, zum Beispiel in der Arbeitsfunktion. Es folgt ein weiterer String, der den Parameter beschreibt, und schließlich der voreingestellte Wert. Der ganze Abschnitt mit den Eingabeparametern sieht so aus:

[
   (PF_INT, "feather_in", "Weicher?
      Rand", 100),
   (PF_INT, "opacity_in", ?
      "Deckkraft", 50)
],

PF_INT steht für eine Ganzzahl (Integer). Die möglichen Parametertypen finden Sie zum Beispiel in der Dokumentation zu Gimp-Python [3], die allerdings etwas veraltet ist – das dort aufgeführte Plugin läuft nicht einmal unter Gimp 2.x. Konsultieren Sie besser die aktuellen Webseiten für Gimp-Perl [4]. Die sind auf dem Laufenden, auch wenn Sie ab und an eine kleine Transferleistung erbringen müssen. Zumindest bei den Parametertypen gibt es keine Unterschiede.

PDB-Funktionen an die Arbeit

Die Arbeitsfunktion muss sich nun erst einmal ihren Namen verdienen, denn bisher tut sie nichts. Eine PDB-Suche nach select findet einige Funktionen. Die richtige heißt gimp_ellipse_select. Der erste Parameter ist das Bild selbst, das dem ersten Parameter der Arbeitsfunktion entspricht. Die folgenden vier geben die Größe der Auswahl an, als X-Wert, Y-Wert, Breite (width) und Höhe (height). Der Parameter option legt fest, ob die Auswahl hinzugefügt wird (CHANNEL_ADD_OP), ob sie eine bestehende ersetzt (CHANNEL_REPLACE_OP) und so fort. Der PDB-Browser zeigt übrigens, wie auch für weitere Parametertypen, geringfügig andere Namen an: zum Beispiel GIMP_CHANNEL_ADD_OP. In Python-Skripts lassen Sie das GIMP_ einfach weg.

Weist man antialias den Wert TRUE zu, glättet Gimp die Auswahllinie. Genauso funktioniert feather, das für einen stufenweisen Übergang sorgt. Der letzte Parameter feather_radius legt die Breite dieses Übergangs fest. Im Skript steht an dieser Stelle kein fester Wert, sondern die Eingabevariable feather_in, die der Benutzer verändern kann (Zeile 5 in Listing 2).

Listing 2

Arbeitsfunktion

def python_vignette(img, drawable, feather_in, opacity_in):
   width = drawable.width
   height = drawable.height
   pdb.gimp_ellipse_select(img, 0, 0, width, height, CHANNEL_OP_REPLACE, TRUE, TRUE, feather_in)
   pdb.gimp_selection_invert(img)
   pdb.gimp_edit_bucket_fill(drawable, FG_BUCKET_FILL, MULTIPLY_MODE, opacity_in, 0, 0, 0, 0)
   pdb.gimp_selection_none(img)

Alle bisher verwendeten Methoden gehören zum Objekt pdb, werden also nach dem Schema pdb.methode() aufgerufen. Deshalb kann man kaum noch von Objektorientierung sprechen, denn die zeichnet sich ja gerade dadurch aus, dass Methoden und Objekte sachlich zusammengehören. Allerdings kennt Gimp-Python auch objektorientierte Formulierungsalternativen: zum Beispiel funktioniert statt pdb.gimp_add_layer(img, ...) auch img.add_layer(...). Das heißt, man ruft die Methode gimp_add_layer() des Objekts img auf, dafür fällt img als Parameter weg. In dieser Form sind die Funktionen im PDB-Browser nicht dokumentiert, sodass wieder Forschungsarbeit nötig wird.

Die Methode gimp_selection_invert kehrt einfach die aktuelle Auswahl um. Schließlich füllt gimp_edit_bucket_fill den ausgewählten Bereich mit der aktuellen Vordergrundfarbe. Dafür sorgt der zweite Parameterwert FG_BUCKET_FILL; stünde hier PATTERN_BUCKET_FILL, würde das Werkzeug das ausgewählten Füllmuster verwenden.

Der folgende Parameter legt fest, auf welche Art die neue Farbebene auf den Hintergrund aufgetragen wird. Der Wert NORMAL_MODE ersetzt die alte Farbschicht einfach. Der im Beispiel verwendete MULTIPLY_MODE sorgt dafür, dass Gimp den alten und den neuen Farbton mischt. Die zur Verfügung stehenden Modi listet unter anderem das Ebenen-Menü auf, die zugehörigen Schlüsselwörter der PDB-Browser (allerdings wieder mit einem überflüssigen GIMP_). Probieren Sie doch mal spaßeshalber DISSOLVE_MODE aus.

Undo abschalten

Beim nächsten Parameter legt der Eingabewert opacity_in die Deckkraft für das Füllen fest. Eine große Zahl sorgt für einen dunkleren, eine kleinere Zahl für einen helleren Rand. Der Vollständigkeit halber entfernt das Skript die Auswahl mit gimp_selection_none wieder. Alle Schritte lassen sich übrigens mit Undo rückgängig machen, denn Gimp führt bei Skripts genauso intern Buch, wie bei der interaktiven Arbeit. Die Funktion gimp_image_undo_disable schaltet diese Buchführung und damit auch Undo ab.

Startet man das Skript mit einem geöffneten Bild, sieht das Ergebnis ungefähr so aus, wie in Abbildung 2. Der Effekt wurde etwas übertrieben gewählt, damit er im Bild besser sichtbar ist. Etwas weniger Deckkraft wäre hier besser. Das komplette Skript finden Sie ebenfalls auf unserem FTP-Server.

Schwieriges Debugging

Eigentlich sollte es einfach sein, Gimp mit Python zu automatisieren. Leider erschwert die veraltete Dokumentation den Einstieg. Auch der Entwicklungszyklus macht die Sache umständlich: Bei jeder Änderung am eigenen Skript ist ein Gimp-Neustart erforderlich. Alleine die Möglichkeit, Skripts bei laufendem Gimp neu zu laden, wäre schon eine Riesenerleichterung.

Die Dokumentation sollte dringend aktualisiert werden. Zur Zeit bleibt dem angehenden Python-Gimp-Programmierer nur, seine Informationen aus verschiedenen Quellen (zum Beispiel auch Gimp-Perl) zusammenzusuchen und sie für die eigene Anwendung zu übersetzen. Lässt er sich davon nicht abschrecken, kann er beim riesige Funktionsumfang für eigene Python-Skripts aus dem Vollen schöpfen.

LinuxUser 02/2005 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben