Skript-Fu: If und While
Aus GIMPForum
| << Bilder per Skript bearbeiten | ^ Inhaltsverzeichnis ^ | Erweiterte Abfragen>> |
If und While
Jeder Programmierer kennt sie, in jeder Programmiersprache sind sie vertreten und ohne sie wären viele Dinge gar nicht erst möglich: If und while. In diesem Kapitel geht es um zwei der wichtigsten Funktionen überhaupt.
Das schlussendliche Skript hier ist vor allem für Zeichner interessant, das Tutorial richtet sich aber an jeden GIMP-User: In diesem Kapitel wirst du ein Skript schreiben, welches ein neues Bild erzeugt, den Benutzer nach der gewünschten Anzahl
für jede Person deines Bildes eine eigene Ebene für die Coloration und eine eigene Ebene für die Outlines erstellt. Zusätzlich kannst du natürlich die Auflösung einstellen und auswählen ob du ein Farb- oder Schwarzweissbild machen möchtest. Zudem kannst du schon im Voraus einen Namen für dein Bild wählen.
Dann legen wir doch gleich los. Erstelle eine neue .scm-Datei und definiere auch gleich die Funktion new-image (Name kannst du frei wählen). Bevor du weiterliest solltest du dir mal selber überlegen, welche Werte du vom Benutzer brauchst und wo bzw. wie du diese aufschreiben musst.
Ich habe mich für folgende Lösung entschieden:
(define (new-image sfImgname sfWidth sfHeight sfRGBImg sfNumOfPers)
Zuerst haben wir die Funktion define um eine Funktion zu erstellen. Als nächstes haben wir die Klammern mit den Parametern, also den Werten, die an die neue Funktion übergeben werden sollen.
new-image ist der Name der Funktion. sfImgname ist der Name des Bildes. sfWidth ist die Breite des Bildes. sfHeight ist die Höhe des Bildes. sfRGBImg wird verwendet um zu überprüfen, ob der Benutzer ein Schwarzweiss- oder RGB-Bild machen will. sfNumOfPers ist die Anzahl der Personen für die der Benutzer Ebenen erstellen lassen möchte.
Ich würde als nächstes gleich den script-fu-register und script-fu-menu-register-Bereich erstellen.
(script-fu-register
"new-image"
"Neues Bild erstellen"
"Erstellt ein neues Bild Outline- und Colorationsebene für die gewünschte Anzahl an Personen."
"created by Mohi"
"Du darfst dieses Skript verteilen und veraendern solange der Name des Autors nicht entfernt wird."
"10. August 2008"
""
SF-STRING "Name des Bildes" "Unbenannt"
SF-ADJUSTMENT "Breite" '(1024 1 262144 1 10 0 1) ;Anfangswert, Mindestwert, Maxwert, kleiner Schritt, grosser Schritt,
;ganze Zahlen(0) oder Fliesskommazahlen(1), Slider (0) oder Rollbox (1)
SF-ADJUSTMENT "Hoehe" '(1024 1 262144 1 10 0 1)
SF-TOGGLE "Farbzeichnung" TRUE
SF-ADJUSTMENT "Anzahl der Personen" '(1 1 10 1 2 0 1)
)
Das einzige was ich hier erläutern möchte, ist der SF-TOGGLE-Parameter. SF-TOGGLE erzeugt eine Checkbox, also ein Kästchen um eine bestimmte Option an oder abzuwählen. Wenn das Kästchen angewählt ist wird der Wert TRUE gesetzt, falls das Kästchen nicht angewählt ist wird der Wert FALSE gesetzt. Dies benötigen wir später um zu entscheiden, ob wir ein Graustufen- oder ein RGB-Bild erzeugen sollen.
(script-fu-menu-register
"new-image"
"<Toolbox>/File"
)
Dies müsste angepasst werden für Gimp2.6.4, alle Variablen müssen einen Anfangswert bekommen! Auch die Registrierung musste anders.
Als nächstes kommt die let*-Funktion um Variablen zu erstellen.
(let*
(;----------Variablendeklaration
(varImg)
(varZaehler 0)
(varActiveLayer)
(varPerson)
(varLayertype)
);----------Variablendeklaration Ende
Als Variablen habe ich... ...varImg; darin wird die ID des Bildes gespeichert. ...varZaehler mit dem Anfangswert 0 wird verwendet um später die Anzahl der bereits erstellten Ebenen zu zählen. ...varActiveLayer um die momentan aktive Ebene zu bearbeiten. ...varPerson habe ich erstellt um später die Ebenen richtig benennen zu können. ...varLayertype wird später verwendet um einer Ebene den richtigen Farbmodus zuzuweisen.
Falls irgendetwas noch nicht klar ist, ist das auch nicht so schlimm. Der Sinn und Zweck jeder einzelnen Variable wird später nochmals genauer erläutert.
Als nächstes erstellen wir zuerst das Bild. Wenn du im Prozeduren-Browser nachschaust, siehst du, dass die Funktion gimp-image-new die Werte width, height und type benötigt. Width und height sollten klar sein, das ist die Grösse des Bildes in Pixel. Type ist der Typ des Bildes, also RGB, GRAY oder INDEXED.
Da wir dem Benutzer die Wahl zwischen RGB- und Graustufenbild lassen wollen müssen wir eine Verzweigung machen. Und solch eine Verzweigung erreichen wir mit der if-Funktion.
If: If kommt aus dem Englischen und bedeutet falls. Die if-Funktion überprüft, ob eine gewisse Bedingung wahr oder falsch ist. Je nach Ergebnis werden dann andere Funktionen ausgeführt:
Der Aufbau von if in Skript-Fu sieht folgendermassen aus:
(if (bedingung) (then-block) (else-block) )
Das heisst, in unserem Fall müssen wir überprüfen, ob der Wert sfRGBImg TRUE oder FALSE ist um dann ein Graustufen- oder ein RGB-Bild zu erzeugen.
Am Besten schreibst du mal selbst diese if-Verzweigung. Wenn der Wert auf TRUE gesetzt ist wird ein RGB-Bild erzeugt, ansonsten ein Graustufenbild. Zusätzlich muss noch der Bildtyp in die Variable varLayertype gespeichert werden (siehe Funktion (gimp-layer-new) für weitere Informationen). Vorlage:Überarbeiten Falls du fertig bist, oder nicht genau weisst, wie das Ganze aussehen soll: hier ist die Lösung:
(if (= sfRGBImg TRUE)
(begin
(set! varLayertype 1) ;RGBA-Ebene ist 1 (gimp-layer-new)
;----------RGB-Bild erstellen
(set! varImg
(car
(gimp-image-new
sfWidth
sfHeight
RGB
)
)
)
)
(begin
(set! varLayertype 3) ;GRAYA-Ebene ist 3 (gimp-layer-new)
;----------Graustufen-Bild erstellen
(set! varImg
(car
(gimp-image-new
sfWidth
sfHeight
GRAY
)
)
)
)
)
Achtung: Wenn du mehrere Anweisungen im Then- oder Else-Block aufrufen willst, muss die Funktion begin verwendet werden:
(if (bedingung)
(begin
(Funktion)
(Funktion)
(Funktion)
)
(begin
(Funktion)
(Funktion)
(Funktion)
)
)
Die nächsten zwei Schritte sind nichts neues: Bild benennen...
;---Bild benennen
(gimp-image-set-filename
varImg
sfImgname
)
...und Hintergrundebene erstellen und einfügen inklusive Inhalt löschen, da GIMP sonst irgendwelche Farbflecken erzeugt. Hier wird auch die Variable varActiveLayer verwendet damit GIMP weiss, welche Ebene mit weiss gefüllt werden soll.
;---Hintergrundebene erstellen
(set! varActiveLayer
(car
(gimp-layer-new
varImg
sfWidth
sfHeight
varLayertype
"Hintergrund"
100
NORMAL-MODE
)
)
)
;---Ebenen einfügen
(gimp-image-add-layer
varImg
varActiveLayer
-1
)
;---Hintergrund mit weiss füllen
(gimp-context-set-foreground '(255 255 255))
(gimp-drawable-fill
varActiveLayer
FOREGROUND-FILL
)
;---Outlineebene für Hintergrund erstellen
(set! varActiveLayer
(car
(gimp-layer-new
varImg
sfWidth
sfHeight
varLayertype
"Hintergrund - Outlines"
100
NORMAL-MODE
)
)
)
;---Ebenen einfügen
(gimp-image-add-layer
varImg
varActiveLayer
-1
)
;---Ebene leerräumen
(gimp-edit-clear varActiveLayer)
Nun kommen wir zur while-Funktion.
While: While kommt ebenfalls aus dem Englischen und bedeutet während oder solange. While wird verwendet um Funktionen solange aufzurufen bis eine Bestimmte Bedingung nicht mehr wahr ist. Einerseits erspart das Schreibarbeit und andererseits kann man so auch Funktionen unterschiedlich häufig mal ausführen lassen. Falls das noch nicht ganz klar ist, liest du am besten einfach mal weiter. Vielleicht löst sich der eine oder andere Knoten in deinem Kopf wenn du die Schleife im Einsatz siehst.
Der Aufbau der while-Schleife sieht folgendermassen aus:
(while (bedingung)
(Funktion)
(Funktion)
(Funktion)
)
Wenden wir das doch mal in unserem Skript an:
Zuerst kommt while und dann die Bedingung.
(while (> sfNumOfPers varZaehler)
Hier siehst du wofür die Variable varZaehler verwendet wird. Solange die Anzahl der Personen (sfNumOfPers) grösser als (>) der Zähler (varZaehler) ist, soll die Schleife durchlaufen werden.
Achtung: Wenn du sfNumOfPers mit varZaehler vertauschen würdest, müsstest du auch die Richtung des grösser als-Zeichens ändern.
Der nächste Teil sieht folgendermassen aus:
(set! varPerson
(number->string (+ varZaehler 1))
)
Dieser Schritt ist nicht zwingend notwendig. Er ist nur für die schönere Beschriftung der Ebenen zuständig, da der Zähler mit 0 beginnt, wir aber i.d.R. mit 1 zu zählen beginnen. (set! varPerson) setzt einen neuen Wert für die Variable varPerson. (number->string) wandelt eine Zahl in Text um. Auch wenn für uns der Text 1 und die Zahl 1 identisch sind, ist das für den Computer nicht dasselbe. Mit einem Text kann er nicht Rechnen und eine Zahl kann er nicht als Text ausgeben. Text (in der Fachsprache String) und Zahl sind unterschiedliche Datentypen. Für weitere Infos zu Datentypen im Allgemeinen: Wikipedia-Artikel
Wir müssen nun einfach den Wert des Zählers erhöhen und ihn dann in einen Text verwandeln. Der nächste Schritt ist derselbe wie bei der Erstellung der Hintergrundebene. Nur bei der Namensgebung ist etwas anders (Erklärung unten).
;---Colorationseben erzeugen
(set! varActiveLayer
(car
(gimp-layer-new
varImg
sfWidth
sfHeight
varLayertype
(string-append "Person " varPerson " - Coloration")
100
NORMAL-MODE
)
)
)
;---Ebenen einfügen
(gimp-image-add-layer
varImg
varActiveLayer
-1
)
;---Ebene leerräumen
(gimp-edit-clear varActiveLayer)
(string-append "Person " varPerson " - Coloration")
Die Funktion string-append fügt mehrere einzelne Zeichenketten (Strings) zu einer einzigen zusammen. In unserem Fall den Text Person mit einem Leerzeichen hintendran, dann den Inhalt der Variable varPerson und zum Schluss den Text - Coloration. Das ist auch der Grund, weshalb wir den Wert auch in einen Text umwandeln mussten, da wir ihn sonst nicht zusammenfügen könnten. Jetzt erhält jede Ebene ihre eigene Nummer, beginnend bei 1.
Ach ja, nicht vergessen: string-append ist keine GIMP-Funktion. Deshalb wird kein car verwendet.
Dann haben wir das Ganze nochmals für die Outlineebene.
;---Outlineebene erzeugen
(set! varPerson
(number->string (+ varZaehler 1))
)
(set! varActiveLayer
(car
(gimp-layer-new
varImg
sfWidth
sfHeight
varLayertype
(string-append "Person " varPerson " - Outlines")
100
NORMAL-MODE
)
)
)
;---Ebenen einfügen
(gimp-image-add-layer
varImg
varActiveLayer
-1
)
;---Ebene leerräumen
(gimp-edit-clear varActiveLayer)
Der nächste Schritt ist sehr wichtig, wenn du mit Schleifen arbeitest. Andernfalls kannst du lange warten, bis das Skript fertig ausgeführt wird.
Wir haben eine Schleife die solange durchlaufen wird, bis die Variable varZaehler nicht mehr kleiner ist als sfNumOfPers. Das bedeutet wir müssen den Zähler varZaehler nach jedem Durchlauf um eins erhöhen. Ansonsten haben wir eine Endlosschleife und GIMP wird nicht reklamieren und eine Warnung ausspucken, dass da eine Endlosschleife vorhanden ist sondern brav die Schleife solange durchlaufen bis die Bedingung nicht mehr erfüllt wird und das ist - ohne Erhöhung des Zählers - nie.
Deshalb die Erhöhung des Zählers:
;---Zähler erhöhen
(set! varZaehler
(+ varZaehler 1)
)
Der Variable einfach den eigenen Wert + 1 zuweisen und gut ist.
Jetzt musst du nur noch die Klammer der while-Schleife schliessen und das Bild anzeigen lassen:
(gimp-display-new varImg) ;Bild anzeigen
Falls du es noch nicht getan hast solltest du nun auch noch die let*- und die define-Klammer schliessen. Speichere das File, aktualisiere die Skripts in GIMP(<Toolbox>/Extras/Skript-Fu/Skripte auffrischen bzw. ab 2.6 Filter/Skript-Fu/Skripte auffrischen) und probier dein Skript gleich mal aus.
Komplettes Skript und dort weiter unten für Gimp 2.6.4
| << Bilder per Skript bearbeiten | ^ Inhaltsverzeichnis ^ | Erweiterte Abfragen>> |
