13 Skripte

Transcription

13 Skripte
HBS GIMP 2
13 Skripte
Jannik Quehl
Und noch ein weiteres Mal darf ich mich an dieser Stelle zu Wort melden, um ein wenig
über das Erstellen von eigenen Filtern und Gimp-Skripten zu erzählen.
Alle Angaben in diesem Kapitel beziehen sich nicht mehr auf Gimp 2.2, sondern auf Gimp
2.4. Jedoch gibt es, was dieses Kapitel angeht, keine nennenswerten Unterschiede
zwischen beiden Versionen, abgesehen davon, dass sich Script-Fu nun unter „Filter“ statt
unter „Extras“ in der Menüleiste befindet.
Im Kapitel 12 haben wir bereits Filter kennengelernt. Gimp hat bereits eine große Anzahl
von zum Teil praktischen, zum Teil weniger nützlichen Filtern vorinstalliert und wenn der
Filter, den man sucht nicht vorhanden ist, so ist er doch meist im Internet nach kurzer
Suche gefunden. Jedoch haben es die Entwickler von Gimp dem User freigestellt, sich
selber auch an der Programmierung von Filtern und Routinen für Gimp zu versuchen.
Script-Fu (bzw. in der Deutschen Gimp-Version Skript-Fu) heißt das Zauberwort, das dies
möglich macht.
Was ist Skript-Fu?
Unter dem Namen Script-Fu versteht Gimp die Möglichkeit mittels
Scheme-Programmierung auf die Gimp-eigene Datenbank
zuzugreifen und so bestimmte Abläufe zu automatisieren.
Grundsätzlich sind hier Gimp keine Grenzen gesetzt. Script-Fu kann
alle Funktionen, Filter und Plugins von Gimp aufrufen und hat so
beinahe so viele Möglichkeiten wie der Nutzer selbst. Das Einzige,
was sich der Automatisierung weitestgehend entzieht, ist der freie
Umgang mit den Werkzeugen, da diese per Hand bewegt und
angewendet werden und so schwierig zu automatisieren sind.
Eine Automatisierung mittels Script-Fu ist insbesondere dann
sinnvoll, wenn sie
− regelmäßig ausgeführt werden sollen, oder
− kompliziert in der Ausführung und so schwer zu merken sind.
Gimp selbst hat bereits etliche Plugins vorinstalliert, die alle auf
Script-Fu-Basis programmiert sind und als Orientierung für eigene
Scripte dienen können. Sie sind aber auch hilfreich als Vorlage zum
Lernen der Programmierung eigener Script-Fu-Plugins.
Wo sich diese Plugins befinden und von wo die eigenen Plugins
geladen werden, kann ganz einfach unter Bearbeiten =>
Einstellungen => Ordner => Skripte eingesehen und eingestellt
werden.
163
HBS GIMP 2
Weitere solche Skripte gibt es in großen Mengen im Internet zu finden. Ihre Installation ist
sehr einfach: Gimp lädt bei jedem Start alle Skripte im richtigen Format aus den in den
Einstellungen angegebenen Ordnern. Das heißt, wenn ein bestimmtes Skript aus dem
Internet in Gimp geladen werden soll, muss es entweder in einen entsprechenden Ordner
gepackt werden, oder es muss der das Skript beinhaltende Ordner in die Ordnerliste
eingefügt werden.
Anschließend kann man entweder
Gimp neu starten, oder – was die
einfachere Methode ist, wenn Gimp
gerade läuft – man wählt unter Filter
=> Skript-Fu => Skripte auffrischen,
um alle Filter und Skripte neu laden
zu lassen.
Das richtige Format für solche
Scripte ist das .scm – Format, das
aber im Prinzip ein normales
Textdokument ist, dessen Endung
von .txt zu .scm geändert wurde und
den Quelltext des Skriptes enthält.
Die Standard-Sprache für Script-Fu-Programmierung ist Scheme, jedoch kann Gimp per
Plugin auch noch weitere Sprachen, wie Perl oder Tcl „lernen“. Diese werde ich jedoch in
diesem Kapitel nicht behandeln. Im Folgenden werde ich eine kurze Einführung in die
Programmiersprache Scheme geben und anschließend anhand eines Beispieles zeigen,
wie das Ganze dann als Gimp-Script aussieht und wie man dann damit arbeitet.
Scheme
Scheme ist eine Variation von der Programmiersprache LISP. Scheme folgt dem Prinzip
der Präfixnotation. Das heißt, dass alle Funktionen bzw. Operatoren vorangestellt werden.
Alle Anweisungen in Scheme stehen in runden Klammern. Hierbei ist das erste Element
der Liste immer die eigentliche Funktion, während die nachfolgenden Elemente Parameter
der Funktion sind. Auch mathematische Operatoren, wie +, -, *, / gelten als Funktionen
und müssen ebenso als erstes Element der Klammer stehen. Eine einfache Addition der
Zahlen 2 und 7 sieht also in Scheme so aus:
(+ 2 7 )
Jedoch ist der Operator + nicht auf 2 Parameter beschränkt. Außerdem ist es möglich,
eine weitere Klammer mit einem weiteren Operator als Element der Liste zu benutzen.
Daher sind auch Rechnungen möglich, wie:
(+ 5 3 (* 4 (- 3 1 )) 1)
164
HBS GIMP 2
Für uns Programmierer hält Gimp dabei ein
besonderes Tool bereit, das uns ermöglicht
ein wenig mit Scheme zu experimentieren:
Die Konsole. Unter Filter => Skript-Fu =>
Konsole, bekommt man die Möglichkeit
einzeilige Scheme-Anweisungen
auszuprobieren und auf ihre Richtigkeit zu
überprüfen.
Geben wir also unsere beiden ersten
Rechnungen ein, so erhalten wir von Gimp
sofort die Ergebnisse. Auffällig ist hierbei,
dass die Klammern von innen nach außen
aufgelöst werden. Eine Punkt-Vor-StrichRegel gibt es nicht, da immer nur ein Operator in einer Klammer steht und erst die inneren
Klammern ausgeführt werden.
Wichtig ist dabei, dass man auf korrekte Leerzeichen achtet. Bei vielen anderen
Programmiersprachen, wie C, C# oder auch Java und Perl ist es erlaubt Leerzeichen
weitestgehend nach Belieben zu setzen. Nicht so in Scheme. Während bei C# zum
Beispiel auch so etwas erlaubt ist, wie: 3+4 , muss bei Scheme nach dem Operator
unbedingt ein Leerzeichen folgen: (+ 3 4) Andernfalls würde Scheme nicht nach dem
Operator + in seiner Datenbank suchen, sondern nach der Funktion +3 , welche er
natürlich nicht finden würde.
Um mit Scheme ein wenig vertraut zu werden, empfiehlt es sich, erst einmal ein paar
einfache Rechenoperationen auszuführen oder vielleicht ein paar Mathematikaufgaben
statt mit dem Taschenrechner mit Scheme zu lösen. Nach einigem Herumprobieren, wird
man sogar feststellen, dass Scheme selbst trigonometrische Rechnungen mühelos
bewältigt, so lange man sich an die richtige Form hält.
Variablen in Scheme
Wie in allen anderen gewöhnlichen Programmiersprachen auch, kann man in Scheme
ebenfalls Variable benutzen. Die einfachste Methode mit Variablen zu arbeiten ist ein let*Konstrukt. Mit let* können lokale Variablen festgelegt werden, welche innerhalb dieses
Konstruktes gültig sind. Das let* - Konstrukt besteht aus 2 Teilen. Im ersten Teil ist es dem
User möglich die Variablen zu deklarieren, während im 2. Teil des Konstruktes diese
Variablen dann verwendet werden können. Die Struktur sieht also so aus:
(let*
( Deklaration der Variablen)
Arbeiten mit den Variablen
)
165
HBS GIMP 2
Dabei ist es egal, ob das ganze als Einzeiler eingegeben wird, oder in mehreren Zeilen –
was in der Gimp-Konsole jedoch nicht möglich ist.
Wir können jetzt zum Beispiel einfach mal zwei Variablen A und B mit den Zahlen 5 und 2
belegen und anschließend miteinander multiplizieren. Das sähe dann so aus:
(let* ( (A 5) (B 2) ) (* A B) )
Was sagt die Gimp-Konsole? 10 – die Rechnung hat funktioniert.
Jeder, der bereits mit anderen Programmiersprachen Kontakt hatte, wird aufgefallen sein,
dass nirgends festgelegt wurde, was für ein Typ die Variablen sind. Sind sie eine
Zeichenkette (String) ? Oder eine Zahl (Double, Int64 etc.)? Sind sie lediglich mit TRUE
oder FALSE belegt (Boolean)?
Die Antwort ist: Es ist egal! Scheme ist eine typfreie Sprache. Man kann Variablen erst
mit einer Zahl belegen, dann mit gleich mehreren Zahlen in einer Liste und auch
Zeichenketten können auf Variablen gelegt werden – alles ohne irgendwann einen Typ in
einen anderen konvertieren zu müssen. Dies spart einiges an Zeit, da nicht ständig hin
und her konvertiert werden muss, jedoch kann es nach wie vor zu Fehlern kommen, wenn
eine Funktion mit falschen Parametern gefüttert wird. Nach der Deklaration einer
Variablen, kann der Variablen innerhalb des let*-Konstruktes jederzeit ein neuer Wert
zugewiesen werden. Dies passiert mit der set!-Anweisung. Im Folgenden sehen sie, wie
der Variablen „dieZahl“ erst der Wert 10 zugeordnet wird... und dann?
(let* ( (dieZahl 5) ) (set! dieZahl (+ dieZahl dieZahl) ) )
zur Übung: Gebt diese Zeile in die Gimp-Konsole ein und überlegt euch, was
herauskommen muss, bevor auf Enter gedrückt wird. Waren eure Vermutungen richtig?
Nicht nur eigene Variablen, sondern auch eigene Funktionen können in Scheme deklariert
werden. Dies passiert mit define ganz ähnlich, wie beim let*-Konstrukt:
(define
(
Funktionsname
Parameterliste
)
Was soll die Funktion tun?
)
Auch hier ist es gleichgültig, ob wir eine Zeile, oder mehrere Zeilen verwenden.
166
HBS GIMP 2
Um zum Beispiel eine Funktion namens Plus, die einfach zwei Zahlen addiert, zu
definieren und anschließend auf die Zahlen 7 und 8 anzuwenden müsste man Folgendes
in die Gimp-Konsole eingeben:
(define (Plus A B) (+ A B) )
Anschließend gibt man dann nur noch
(Plus 7 8)
ein und erhält sofort als Ergebnis 15.
Wer sich bereits mit Programmieren einigermaßen auskennt, dem fällt sofort auf, dass wir
keine Angaben darüber gemacht haben, was diese Funktion letzten Endes ausgeben soll.
Scheme gibt immer das Ergebnis der letzten Anweisung innerhalb der Funktion aus.
Listen
Ein weiteres wichtiges Element für die Script-Fu Programmierung sind Listen. Die meisten
Gimp-Funktionen geben als Ergebnis keine konkreten Werte aus, sondern stattdessen
Listen. Listen sind – wie der Name bereits vermuten lässt – eine Aneinanderreihung von
mehreren Elementen. Diese Elemente können Zeichenketten, Zahlen und sogar selber
eigene Listen sein. Eine Liste muss nicht einmal nur Elemente der gleichen Art beinhalten
und Listen können selber auch auf Variablen geschrieben werden. Eine Liste deklariert
man mit '(). Das sieht dann zum Beispiel so aus:
'(1 2 3)
Um innerhalb einer Liste eine weitere Liste zu deklarieren, wird das ' nicht noch ein
weiteres Mal benötigt:
'(1 (2 3) 4)
Neben '(Listenelemente) gibt es noch weitere Möglichkeiten Listen zu erzeugen, wie die
cons-Anweisung, welche zwei Listen verbindet, oder die list-Anweisung, welche die Werte
der Variablen als Listenelemente ausliest, jedoch interessieren die im Rahmen dieser
Einleitung nicht. Wichtig jedoch ist noch die Art und Weise auf die man einzelne
Listenelemente auslesen kann.
Eine Liste muss man sich als aus zwei Teilen bestehend vorstellen: Dem ersten Element,
dem Kopf und dem Rest der Elemente dem Schwanz. Der Befehl car liest den Kopf der
Liste aus, während der Befehl cdr den Schwanz ausliest. Um ein bestimmtes Element der
Liste auszulesen, kombiniert man jetzt diese beiden Befehle, um sich zum richtigen Glied
durchzuarbeiten.
167
HBS GIMP 2
Dabei kann man
(car (cdr (cdr '(1 2 3 4 5) ) ) )
(das erste Element des Restes des Restes – also 3) auch schreiben als:
(caddr '(1 2 3 4 5) )
wobei beliebig viele a bzw. d zwischen das c und das r eingefügt werden können.
Skript – Fu
So viel zu Scheme allgemein. Wie sieht das ganze jetzt konkret aus, wenn wir einen Filter
programmieren wollen?
Für diese Einführung habe ich mich dafür entschieden einen relativ einfachen Schrifteffekt
zu automatisieren:
Dabei darf der Benutzer eine ganze Menge eingeben:
1. Was soll da stehen?
2. Welche Schriftart soll verwendet werden?
3. Welche Textgröße?
4. Schriftfarbe?
5. Hintergrundfarbe?
6. Die Farbe des inneren Glühens?
7. Die Farbe des äußeren Glühens?
8. Die stärke des Gaußschen Weichzeichners
9. Der Radius des Glühens
10. Wie viel Platz soll außen herum gelassen werden?
11. Sollen am Ende alle sichtbaren Ebenen vereint werden?
Der Vorgang ist schnell erklärt:
Es wird ein Text erstellt, aus dessen Alphakanal eine Auswahl erstellt wird. Die Auswahl
wird vergrößert und in einer neuen Ebene mit der Farbe des inneren Glühens gefüllt.
Anschließend wird die Auswahl erneut vergrößert und wieder in einer neuen Ebene mit der
Farbe des äußeren Glühens gefüllt. Die Bildgröße wird an die Größe der Textebene
angepasst und die beiden neuen Ebenen werden weichgezeichnet. Zum Schluss muss
nur noch die Hintergrundfarbe angepasst und die Ebenen in die richtige Reihenfolge
gebracht werden.
168
HBS GIMP 2
Versuchen wir also das ganze umzusetzen. Um mit Scheme zu programmieren müssen
wir uns zuerst einmal ein dafür geeignetes Programm zulegen. Prinzipiell reicht dafür
jedes Programm, das .txt – Dateien öffnen und bearbeiten kann. (wie z.B. der Editor für
Windows) Ich persönlich favorisiere das Notepad++, ein einfaches Freeware-Tool, das
einfache Strukturen, wie zum Beispiel Klammern erkennt und so eine gute Strukturierung
des Quellcodes ermöglicht.
Mit diesem – oder einem anderen – Editor öffnen wir jetzt einfach ein neues leeres
Textdokument (.txt) und benennen es so um, dass die Endung nun .scm lautet. Alles was
wir jetzt an diesem Skript programmieren wird in dieser Datei abgespeichert. Um das
Skript anschließend auszuprobieren, muss es, wie oben beschrieben, in den Skript-Ordner
von Gimp kopiert werden.
Beginnen wir also nun mit der Erstellung des Skriptes.
Ein Skript-Fu-Skript braucht allgemein folgende Elemente:
1. Die Definition der Hauptfunktion des Skriptes, die aufgerufen wird, sobald das
Skript gestartet wird
2. Einen Aufruf der script-fu-register Anweisung, die angibt, was der User selber
eingeben darf und wie sich das Script dem Benutzer präsentiert. Diese Funktion
wird benötigt um das Skript in der Gimp-Datenbank zu registrieren und so den
Zugriff von Gimp aus zu ermöglichen
3. Einen Aufruf der script-fu-manu-register Anweisung, welche angibt, wo man das
Skript in Gimp finden kann
Wo diese Elemente sich im Skript befinden ist irrelevant, ich stelle sie jedoch voran an den
Anfang des Skriptes, damit ich diese Elemente und den Rest auch optisch auseinander
halten kann.
Anmerkung:
Im Folgenden werde ich die wesentliche Vorgehensweise, sowie den Aufbau meines
Skriptes beschreiben, werde dabei jedoch nicht mein gesamtes Skript hier durchgehen.
Am Ende dieses Kapitels findest Du (aus Platzgründen) die undokumentierte Version des
Skriptes. Die ausführlich dokumentierte fertige scm-Datei kann gesondert
heruntergelassen werden.
Fangen wir also an:
Als erstes wird die Registrierung des Skriptes bei Gimp vorgenommen. Dafür rufen wir die
Gimp-Funktion script-fu-register auf. Die Parameter dieser Funktion beschreiben als erstes
wesentliche Eigenschaften des Skriptes, während die nachfolgenden definieren, was der
Benutzer auf welche Art und Weise eingeben darf:
169
HBS GIMP 2
der erste Teil:
(script-fu-register
"script-fu-text-glowing"
"Gluehende Schrift"
"Erstellt einen einfachen Text\
und fuegt ihm ein Glühen hinzu"
"Jannik Quehl"
"Copyright (c) 2008 Jannik Quehl."
"Dezember 2008"
""
Als erstes steht der Name der Funktion, die von uns im Skript definiert werden wird.
Der zweite Parameter gibt dem ganzen Skript einen Namen
Es folgt eine kurze Beschreibung des Skriptes. \ gibt dabei einen Zeilenumbruch wieder.
Als nächstes darf sich der Autor des Skriptes verewigen.
Dann kommen Anmerkungen zum Copyright. (z.B. nach der GPL)
Der sechste Parameter soll sagen, wann das Skript erstellt wurde.
Und der letzte hier angegebene Parameter soll sagen, auf welchen Bildtypen dieses Skript
arbeitet. (RGB, GRAY etc.) Da durch dieses Skript ein neues Bild erstellt wird, können wir
dieses Feld frei lassen.
Anschließend gibt jeder weitere Parameter eine Eingabemöglichkeit für den Benutzer an.
Als erstes gibt man dabei an, um was für eine Art von Eingabemöglichkeit es sich handelt.
Als nächstes erfolgt die Beschriftung dieser Eingabe und als letztes erfolgen die
Voreinstellungen:
SF-STRING
SF-FONT
SF-ADJUSTMENT
SF-COLOR
SF-COLOR
SF-COLOR
SF-COLOR
SF-ADJUSTMENT
SF-ADJUSTMENT
SF-ADJUSTMENT
SF-TOGGLE
"Text"
"Hallo"
"Schriftart"
"Arial Bold"
"Textgroesse"
'(50 1 1000 1 10 0 1)
"Schriftfarbe"
'(0 0 0)
"Hintergrundfarbe" '(0 0 0)
"Gluehen 1"
'(255 255 255)
"Gluehen 2"
'(0 0 255)
"Weichzeichnen"
'(10 1 100 1 10 1 0)
"Gluehradius"
'(2 1 20 1 10 1 0)
"Platz aussen"
'(100 0 300 1 10 1 0)
"Sichtbare Ebenen vereinen?" TRUE
)
SF-STRING gibt hier zum Beispiel an, dass die Eingabemöglichkeit eine einfache Textbox
ist, in welcher als Text bereits „Hallo“ eingetragen ist. Beschriftet ist die Box mit „Text:“
wobei der Doppelpunkt von Gimp automatisch hinzugefügt wird.
170
HBS GIMP 2
Auf der Abbildung rechts kann man sehen,
welcher Art von SF-Parametern welche
Eingabemöglichkeit als Resultat hat.
Auffällig ist, dass sowohl der Parametertyp SFCOLOR, als auch SF-ADJUSTMENT aus Listen
bestehen, welche von Gimp eingelesen werden.
Bei SF-COLOR entsprechen die drei Elemente
den Farbwerten der RGB – Farben (nein, nicht
rosa, grau, braun, sondern Rot, Grün, Blau). Bei
SF-ADJUSTMENT gibt das erste Element die
Voreinstellung an, das 2. das Minimum, das 3.
das Maximum der einstellbaren Werte. Element 4
gibt die Schrittgröße an in der der Wert verstellt
wird, wenn die kleinen Pfeile verwendet werden.
Das Element 5 gibt die Schrittgröße an wenn Bild
hoch / runter verwendet wird und Element 6 sagt
die Anzahl der Nachkommastellen an. Der letzte
Wert gibt an, was für eine Eingabeart verwendet
werden soll. (zum Vergleich Textgröße hat den
Wert 1, die anderen SF-Adjustment den Wert 0)
Als nächstes müssen wir Gimp sagen, wo es das
Skript hin packen soll. Das machen wir dieses Mal mit der Funktion script-fu-menuregister.
(script-fu-menu-register
"script-fu-text-glowing"
"<Toolbox>/Xtns/Skript-Fu/Text")
Der erste Parameter hierbei ist der Name der Funktion dieses Skriptes. Der zweite gibt
den Pfad an. Bei diesem Beispiel erscheint das Skript unter Filter => Skript-Fu => Text =>
Gluehende Schrift.
Die letzte Anweisung, die unbedingt benötigt wird, um ein Skript-Fu-Skript auszuführen, ist
das Definieren der eigentlichen Funktion. Dies geschieht, wie oben bereits geschrieben
mit dem Befehl define. Zusätzlich zum Namen der Funktion unter dem Gimp dieses Skript
ausführen kann, müssen in der Define-Anweisung alle Parameter angegeben werden mit
denen das Skript arbeiten wird. Damit alle Eingaben des GUI richtig verarbeitet werden,
muss die Reihenfolge der Parameter dieselbe sein, wie die der Eingaben in der Funktion
script-fu-register (siehe oben). Bei meinem Script sieht das ganze dann so aus:
171
HBS GIMP 2
(define
(script-fu-text-glowing
inText inSchriftart inTextgroesse inSchriftfarbe
inHintergrundfarbe inGluehen1 inGluehen2 inWeichzeichnen
inGluehradius inPlatzaussen inVereinen)
;hier kommt alles rein was die Funktion tun soll
)
Kurz zur Namensgebung: Um beim Programmieren der Funktion nicht durcheinander zu
kommen, benenne ich alle Eingabewerte, die an die Funktion als Parameter gegeben
werden, mit der Vorsilbe „in“. (z.B. inText als Eingabe des SF-STRING Wertes)
Lokalen Variablen hingegen, welche ich später in der let*-Funktion definiere, werde ich
jeweils ihren Artikel als Vorsilbe voranstellen, um sie eindeutig erkennen und ihre Namen
einfacher merken zu können. (z.B. dieBildbreite als Variable auf die später die breite des
Bildes in Pixeln gelegt wird) Natürlich ist jedem freigestellt, seine Parameter und Variablen
nach eigenem Belieben zu benennen, jedoch kann ich empfehlen, sich dabei an
bestimmte selbst festgelegte Regeln zu halten, damit eine gewisse Ordnung erhalten
bleibt und das Skript leicht zu verstehen ist. Außerdem wird bereits aufgefallen sein, dass
ich Umlaute, sowie das ß innerhalb des Skriptes vermeide. Gimp hat nämlich mit
Sonderzeichen so seine Probleme und stellt diese meistens nicht korrekt dar.
Bevor wir nun jedoch zu dem Punkt kommen, an dem wir sagen müssen, was tatsächlich
getan werden soll, müssen wir erst noch unsere Variablen definieren. In meinem Skript
habe ich das ganze, wie oben beschrieben, mit lokalen Variablen und der let* - Funktion
verwirklicht. Wir basteln uns also eine let*-Struktur zusammen und fangen an unsere
Variablen zu deklarieren:
(let*(
(dieBildbreite 5)
(dieBildhoehe 5)
(derText)
(derFreiraum)
(dasGluehen1)
(dasGluehen2)
(derRadius)
(dasBild(car (gimp-image-new dieBildbreite dieBildhoehe
RGB) ) )
(dieEbene1 (car (gimp-layer-new dasBild dieBildbreite
dieBildhoehe RGB-IMAGE „ebene 1“ 100 Normal) ) )
)
;hier kommt dann hin, was mit den Variablen angestellt werden soll
)
172
HBS GIMP 2
Wir haben in diesem Skript also jetzt insgesamt neun Variablen deklariert, die wir nun im
2. Teil der let*-Struktur zum programmieren benutzen können. Vier der Variablen haben in
der Deklaration auch gleich noch einen Wert zugeordnet bekommen: dieBildbreite und
dieBildhoehe haben jeweils den Wert 5 zugewiesen bekommen. Mit diesen beiden Werten
wurde mit Hilfe der Gimp-Funktion gimp-image-new Funktion ein neues Bild erstellt, das
vorerst nur die Größe 5 x 5 Pixel besitzt und auf die Variable dasBild gelegt wird. Auch
dieEbene 1 hat etwas zugewiesen bekommen, nämlich eine neue Ebene, welche im Bild
dasBild angelegt wird.
Wie man sieht, braucht man jetzt immer mehr
gimpeigene Funktionen, da man sonst keine
Möglichkeit hat mit Gimp zu kommunizieren.
Jedoch kann sich wohl niemand alle Funktionen
und Parameter merken, die die umfangreiche
Gimp-Bibliothek zur Verfügung stellt. Doch zum
Glück kann man bei Gimp alles was man wissen
muss finden. Unter Hilfe => ProzedurenBrowser besteht nämlich die Möglichkeit sich
alle Funktionen, die in Gimp bereits definiert
sind, mit Parametern und Erklärung anzeigen zu
lassen. Über die Suche des
Prozedurenbrowsers finden sich so schnell alle
Funktionen, die man benötigt.
Zur Übung: Sucht im Prozeduren-Browser die Funktion gimp-layer-new, mit der wir
dieEbene1 deklariert haben und versucht nachzuvollziehen, was die Parameter bedeuten,
die in der Deklaration zu sehen sind.
Nachdem wir also unsere Variablen deklariert haben, fangen wir nun endlich mit dem
richtigen Programmieren an. Im 2. Teil der let*-Struktur kann man, wie bereits erklärt, nun
mit den Variablen Programmieren. Das Programmieren sieht im Wesentlichen so aus,
dass der Programmierer der Reihe nach die Gimp-Prozeduren angibt, die aufgerufen
werden sollen. Dabei sollte man so strukturiert wie möglich vorgehen und am besten den
gesamten Vorgang in mehrere Untervorgänge im Kopf aufzugliedern, die der Reihe nach
durchlaufen werden. Denn der Programmierer muss sich bei der Eingabe jedes einzelnen
Befehls bewusst sein, was bereits geschehen ist, was noch geschehen muss und welche
Variablen dazu notwendig sind – eine gute Übersichtlichkeit ist da ein Muss.
Mein Skript habe ich grob in 5 Schritte aufgeteilt:
1. Bild und Ebene zusammenfügen und die Textebene erstellen
2. Den meisten Variablen Werte zuweisen und die Bildgröße anpassen
3. Das äußere Glühen wird als Ebene eingefügt
4. Das innere Glühen wird als Ebene eingefügt
5. Die Glühebenen werden weichgezeichnet und alles, was noch nicht stimmt, wird
korrigiert
173
HBS GIMP 2
Wie jeder Schritt im Detail aussieht, kann im beiliegenden Script eingesehen werden. Ich
habe zu jedem Funktionsaufruf einen Kommentar hinzugefügt, der erklärt, was dort jeweils
gemacht wird. Kommentare innerhalb des Quellcodes können eingefügt werden, indem
man ihnen ein Semikolon (;) voran stellt. Alles was hinter dem ; steht, wird von Gimp
ignoriert und dient lediglich der Erklärung des Skriptes. Mit den bisherigen Informationen
sollten alle Schritte mit Hilfe des Prozeduren-Browsers für den (eifrigen) Leser dieses
Skriptes nachzuvollziehen sein. Auf einen besonderen Punkt möchte ich zum Schluss
noch eingehen:
If-Abfragen
Gegen Ende des Skriptes befindet sich eine etwas merkwürdige Anweisung:
(if (= inVereinen TRUE)
(gimp-image-merge-visible-layers dasBild EXPAND-AS-NECESSARY)
)
Die if-Abfragen sind eine Möglichkeit bestimmte Zustände abzufragen. Die Struktur dabei
ist:
(if ( Bedingung )
Anweisung(en), die im Falle der erfüllten Bedingung ausgeführt
werden soll
)
In unserem Fall wird abgefragt, ob der Benutzer einen Haken gesetzt hat bei „Sichtbare
Ebenen vereinen?“. Ist dies der Fall, soll Gimp am Ende alle Ebenen, die vom Skript
erstellt wurden, vereinen und so zu einer einzigen zusammenzufügen. Ebenso können
zum Beispiel bestimmte Werte abgefragt werden, oder geprüft werden, ob bestimmte
Werte über oder unter einem bestimmten Wert liegen. Auch hierbei ist jedoch nie die
Präfixnotation zu vergessen, die uns zwingt immer erst die Funktion nach der abgefragt
wird (z.B. <, =, > ...) vor die eigentlichen Parameter zu stellen.
Ausprobieren: Sobald das Skript lauffähig ist, kann das Skript, wie oben beschrieben,
installiert werden. Sobald das Skript dann in Gimp aufgerufen wird, kann getestet werden,
ob alles nach Wunsch funktioniert. Ich empfehle hierbei, das Skript auch vor seiner
endgültigen Fertigstellung öfters in Gimp auszuprobieren, um immer schon zu wissen, ob
man bereits Fehler gemacht hat, denn sobald die Grundstruktur des Skriptes steht, sollte
es auch ohne Fehlermeldung ausgeführt werden können. In Zeiten der Trial-and-ErrorProblemlösung ist dies vermutlich sowieso der Weg den die Meisten einschlagen, um mit
der Programmierung eigener Skripte voranzukommen. Wichtig ist nur, dass man die finale
Version des Skriptes gründlich testet, indem man überprüft ob jede einzelne
Benutzereingabe den gewünschten Effekt erzielt und ausprobiert, ob es nicht doch
irgendwo zu einer Fehlermeldung kommen kann.
Zusammenfassung: Hier noch einmal das einfachste Gerüst, aus dem sich das Skript
174
HBS GIMP 2
zusammensetzt, und nach dessen Vorbild man ebenfalls andere Skripte gestalten kann:
(script-fu-register PARAMETER)
(script-fu-menu-register PARAMETER)
(define (Name_der_Funktion PARAMETER)
(let* (VARIABLEN)
ANWEISUNGEN
)
)
Schlusswort:
Gimp als Open-Source-Programm ist darauf angewiesen, dass es immer Leute gibt, die
ohne finanzielles Interesse helfen wollen, Gimp weiterzuentwickeln und neue Fähigkeiten
beizubringen. Photoshop ist nach wie vor die Referenz wenn es um professionelle
Bildbearbeitung geht, doch ist Photoshop auch sehr teuer und für Hobby-Fotographen und
Laien lohnt sich eine Anschaffung oft nicht. Mit Skript-Fu liegt es jedoch in der Hand jedes
einzelnen Gimp-Nutzers das Programm ihrer Wahl auf eigene Faust zu verbessern und
den eigenen Bedürfnissen anzupassen. Heute gibt es in verschiedenen Communities rund
um Gimp unzählige Filter, Skripte und Plugins von Benutzern für Benutzer, die zum Teil
großartige Arbeit leisten und manchmal sogar ihren Weg in das nächste Stable-Release
von Gimp schaffen. (Man denke nur an das Siox-Plugin zum Freistellen von Objekten im
Vordergrund) Das Ziel meiner kleinen Einführung in Skript-Fu ist es nicht einen perfekten
Einblick in die Feinheiten der Programmiersprache Scheme zu geben, oder dem Leser
beizubringen großartige Filter aus dem Ärmel zu schütteln. Stattdessen soll diese
Einleitung nur andeuten, dass es prinzipiell jedem mit ein wenig Lernaufwand möglich ist,
seine eigenen Ideen zur Fotobearbeitung in Gimp zu realisieren und die einfachsten
Grundlagen hierfür festhalten.
Wer Gefallen an Skript-Fu gefunden hat und mehr lernen möchte, dem kann ich nur
empfehlen unterschiedliche Skripte anderer Programmierer durchzulesen und
nachzuvollziehen. Ansonsten ist der beste Weg meiner Meinung nach immer noch der des
learning-by-doing-Prinzips. (Man könnte zum Beispiel nach Tutorials für Gimp googlen und
versuchen solche Tutorials mit Skript-Fu zu automatisieren)
Meine persönlichen Favoriten, wenn es um Gimp und Skript-fu geht sind:
http://gimpforum.de/ Eine nette Community rund um Gimp. (Hat ein tolles Gimp-Wiki mit
vielen Tutorials)
http://registry.gimp.org/ Ein sehr umfangreiches Archiv mit unzähligen Filtern, Plugins und
Skripten.
http://www.gimpusers.de/ Alles rund um Gimp.
175
HBS GIMP 2
Unkommentiertes Script:
(Textboxscript.scm)
(script-fu-register
"script-fu-text-glowing"
"Gluehende Schrift"
"Erstellt einen einfachen Text\
und fuegt ihm ein Gluehen hinzu"
"Jannik Quehl"
"Copyright (c) 2008 Jannik Quehl."
"Dezember 2008"
""
SF-STRING
"Text"
"Hallo"
SF-FONT
"Schriftart"
"Arial Bold"
SF-ADJUSTMENT "Textgroesse"
'(50 1 1000 1 10 0 1)
SF-COLOR
"Schriftfarbe" '(0 0 0)
SF-COLOR
"Hintergrundfarbe" '(0 0 0)
SF-COLOR
"Gluehen 1"
'(255 255 255)
SF-COLOR
"Gluehen 2"
'(0 0 255)
SF-ADJUSTMENT "Weichzeichnen" '(10 1 100 1 10 1 0)
SF-ADJUSTMENT "Gluehradius"
'(2 1 20 1 10 1 0)
SF-ADJUSTMENT "Platz aussen" '(100 0 300 1 10 1 0)
SF-TOGGLE
"Sichtbare Ebenen vereinen?" TRUE
)
(script-fu-menu-register "script-fu-text-glowing" "<Toolbox>/Xtns/Skript-Fu/Text")
(define (script-fu-text-glowing inText inSchriftart inTextgroesse inSchriftfarbe inHintergrundfarbe
inGluehen1 inGluehen2 inWeichzeichnen inGluehradius inPlatzaussen inVereinen)
(let*
(
(dieBildbreite 5)
(dieBildhoehe 5)
(dasBild(car
(gimp-image-new
dieBildbreite
dieBildhoehe
RGB
)
)
)
(derText)
(derFreiraum)
(dieEbene1
(car
(gimp-layer-new
dasBild
dieBildbreite
dieBildhoehe
RGB-IMAGE
"ebene 1"
100
NORMAL
)
)
)
176
HBS GIMP 2
(dasGluehen1)
(dasGluehen2)
(derRadius)
)
(gimp-image-add-layer dasBild dieEbene1 0)
(gimp-context-set-background inGluehen2 )
(gimp-context-set-foreground inSchriftfarbe)
(gimp-drawable-fill dieEbene1 BACKGROUND-FILL)
(set! derText (car
(gimp-text-fontname
dasBild
-1
00
inText
0
TRUE
inTextgroesse PIXELS
inSchriftart)
)
)
(set! dieBildbreite (car (gimp-drawable-width derText) ) )
(set! dieBildhoehe (car (gimp-drawable-height derText) ) )
(set! derFreiraum (* dieBildhoehe (/ inPlatzaussen 100) ) )
(set! dieBildhoehe (+ dieBildhoehe derFreiraum derFreiraum) )
(set! dieBildbreite (+ dieBildbreite derFreiraum derFreiraum) )
(gimp-image-resize dasBild dieBildbreite dieBildhoehe 0 0)
(gimp-layer-resize-to-image-size dieEbene1)
(gimp-layer-set-offsets derText derFreiraum derFreiraum)
(gimp-selection-layer-alpha derText)
(gimp-selection-grow dasBild (+ inGluehradius inGluehradius))
(gimp-edit-copy dieEbene1)
(gimp-edit-paste dieEbene1 FALSE)
(set! dasGluehen2 (car (gimp-image-get-floating-sel dasBild)))
(gimp-floating-sel-to-layer dasGluehen2)
(gimp-layer-resize-to-image-size dasGluehen2)
(gimp-context-set-background inGluehen1 )
(gimp-drawable-fill dieEbene1 BACKGROUND-FILL)
(gimp-selection-layer-alpha derText)
(gimp-selection-grow dasBild inGluehradius)
(gimp-edit-copy dieEbene1)
(gimp-edit-paste dieEbene1 FALSE)
(set! dasGluehen1 (car (gimp-image-get-floating-sel dasBild)))
(gimp-floating-sel-to-layer dasGluehen1)
(gimp-layer-resize-to-image-size dasGluehen1)
(gimp-context-set-background inHintergrundfarbe )
(gimp-drawable-fill dieEbene1 BACKGROUND-FILL)
(set! derRadius inWeichzeichnen)
(plug-in-gauss-rle2 TRUE dasBild dasGluehen2 derRadius derRadius)
(plug-in-gauss-rle2 TRUE dasBild dasGluehen1 derRadius derRadius)
(gimp-image-raise-layer dasBild derText)
(gimp-image-raise-layer dasBild derText)
(if (= inVereinen TRUE)
177
HBS GIMP 2
(gimp-image-merge-visible-layers dasBild EXPAND-ASNECESSARY)
)
(gimp-display-new dasBild)
)
)
178