Das bißchen Script-Fu macht sich von allein … (Part 2)

ClaraFall
Beiträge: 99
Registriert: Di 5. Jul 2011, 20:36
Skype:
Kontaktdaten:

Das bißchen Script-Fu macht sich von allein … (Part 2)

Beitragvon ClaraFall » Sa 10. Mär 2012, 18:56

Hallo Ihr Lieben

Dann wollen wir mal weitermachen.
Aber zuerst gibt es eine kleine:


Wiederholung

Im ersten Part haben wir gelernt, daß ein Skript-Fu-Skript aus drei Teilen besteht:

  • Dem Skript, das alle Anweisungen und Befehle enthält
  • Dem (script-fu-register), das GIMP veranlaßt unser Skript einzulesen sowie die Interaktionsmaske zu erstellen und
  • Dem (script-fu-menu-register), daß GIMP sagt, wo das Skript zu finden ist.
Zuvor müssen sich allerdings ausreichend Gedanken gemacht werden,
was das Skript überhaupt anstellen soll und welche Werte (Parameter) gebraucht werden.

Dabei können völlig verschiedene Ergebnisse herauskommen, je nachdem, wie viele Funktionen das Skript erledigen können soll, wie viele Parameter dem Skript übergeben werden sollen und wie einfach (oder kompliziert) das Skript zu händeln sein soll.


Programmieren

Zur Lösung unseres Problems hatte ich mal 3 unterschiedliche Varianten vorgestellt.
Vielleicht ist es ja jemanden aufgefallen, aber bei allen drei Versionen sind die Vorbelegungen, also die Standardwerte so eingestellt, daß bei ihrer Nutzung, das gleiche Ergebnis herauskommen würde.
Es würden alle vorhandenen Hilfslinien gelöscht und drei horizontale und drei vertikale Hilfslinien gesetzt werden. Jeweils bei 25, 50 und 75 Prozent.

Aber wie machen wir das nun?
Wie programmieren wir so etwas?
Wie programmieren wir überhaupt?

Eigentlich ist es gar nicht kompliziert
Es ist nur ein wenig Kopfarbeit gefragt…
Wir schreiben einfach ein Tutorial
Was würden wir machen, um dieses Problem mit Maus und Tastatur zu lösen.

Hierbei müssen wir nicht auf Schönschrift, Rechtschreibung oder hübsch ausformulierte Sätze achten, sondern darauf, daß es so genau wie möglich ist.

Das schreiben wir einfach der Reihe nach auf.

Da wir Hilfslinien setzen wollen, gehen wir mal davon aus, daß GIMP bereits gestartet und ein Bild geöffnet ist
In unserem Fall könnte unser Tutorial z.B. so aussehen:

  • Klicke im Menü auf BILD / Hilfslinien / Alle Hilfslinien entfernen
  • Klicke im Menü auf BILD / Hilfslinien / Neue Hilfslinie (in Prozent) …
  • Stelle Hilfslinie auf Horizontal
  • Stelle Position auf 25
  • Gebe OK
  • Klicke im Menü auf BILD / Hilfslinien / Neue Hilfslinie (in Prozent) …
  • Stelle Hilfslinie auf Horizontal
  • Stelle Position auf 50
  • Gebe OK
  • Klicke im Menü auf BILD / Hilfslinien / Neue Hilfslinie (in Prozent) …
  • Stelle Hilfslinie auf Horizontal
  • Stelle Position auf 75
  • Gebe OK
  • Klicke im Menü auf BILD / Hilfslinien / Neue Hilfslinie (in Prozent) …
  • Stelle Hilfslinie auf Vertikal
  • Stelle Position auf 25
  • Gebe OK
  • Klicke im Menü auf BILD / Hilfslinien / Neue Hilfslinie (in Prozent) …
  • Stelle Hilfslinie auf Vertikal
  • Stelle Position auf 50
  • Gebe OK
  • Klicke im Menü auf BILD / Hilfslinien / Neue Hilfslinie (in Prozent) …
  • Stelle Hilfslinie auf Vertikal
  • Stelle Position auf 75
  • Gebe OK
Fertig wäre unser Tutorial.

Wenn wir diese aufgeschriebenen Anweisungen nacharbeiten oder besser noch, von jemanden nacharbeiten lassen, der GIMP überhaupt nicht kennt, und unser gewünschtes Ergebnis wird erreicht, dann haben wir bereits unser erstes Programm geschrieben, denn ein Programm ist nichts anderes, als eine Aneinanderreihung von Befehlen und Kommandos.

Jetzt müssen wir eigentlich nur noch dem Computer also GIMP mitteilen, daß es genau diese Schritte in genau der aufgeschriebenen Reihenfolge auszuführen hat.
Dafür müssen wir lediglich unsere Anweisungen in Skript-Fu Befehle übersetzen.

Skript-Fu kennt zwei Arten von Befehlen
Sheme und
GIMP-PROCEDUREN
Bevor wir jetzt unsere Befehle in Skript-Fu verständliche Anweisungen übersetzen,
kommen noch ganz kurz ein paar einleitende Zeilen.


SHEME

Wie eibauoma bereits bemerkte, ist Sheme und somit auch Skript–Fu ein Sensibelchen,
genauer gesagt "CASE-SENSITIVE", was soviel bedeutet es ist sensibilisiert, was die Groß- und Kleinschreibung betrifft.
Achtet also immer auf die exakte Schreibweise.

Parameterübergabe
Woher weiß unser Skript eigentlich, welche Werte wir eingestellt haben?
Im Augenblick natürlich noch gar nicht.
Parameter werden einem Skript immer, unmittelbar durch Leerzeichen getrennt, nach dem Skriptnamen übergeben.
Unser Skript bestand ja bisher nur aus zwei Zeilen, der (define) Zeile und der Endezeile.

Code: Alles auswählen

; Teil 1 Das Script
;======================================================
(define (script-fu-hilfslinien)    ; hier beginnt "script-fu-hilfslinien"
)                                  ; und hier endet "script-fu-hilfslinien"


Wenn wir unserem Skript z.B. 4 Parameter aus der ersten Variante übergeben wollen:
- Das Bild
- Entscheidung, ob Hilfslinien zuerst gelöscht werden
- Anzahl der zu setzenden horizontalen Hilfslinien
- Anzahl der zu setzenden vertikalen Hilfslinien

Dann könnte unser Skript etwa so aussehen:

Code: Alles auswählen

; Teil 1 Das Script
;======================================================
(define (script-fu-hilfslinien par1 par2 par3 par4)   
)


Hier haben wir die Parameter einfach par genannt.
Das ist nicht sehr vielsagend und wir müßten uns merken, was jeder Parameter bedeutet.
Also geben wir den Parametern aussagekräftigere Namen.

Code: Alles auswählen

; Teil 1 Das Script
;======================================================
(define (script-fu-hilfslinien p-Bild p-Loeschen p-anzH p-anzV)   
)


Bei der Vergabe der Parameternamen habt Ihr völlig freie Wahl, nur Umlaute dürfen nicht genommen werden sowie Leerzeichen.

Übrigens werden die Parameter in genau der Reihenfolge übergeben,
wie Ihr sie unter (script-fu-menu-register) angebt.
Solltet Ihr also mal die Reihenfolge bei der Eingabemaske ändern oder Parameter hinzufügen oder entfernen, so müßt Ihr dies auch unbedingt in der Parameterübergabezeile anpassen.

Variablen
Außer den übergebenen Parameter werden zur Bearbeitung noch weitere Werte benötigt.
Da die nicht im luftleeren Raum liegen können, werden sie an bestimmten Stellen im Speicher abgelegt.
Weil sich diese abgespeicherten Werte ändern können, variabel sind, werden diese Stellen auch Variablen genannt.
Damit wir diese Stellen also diese Variablen auch wiederfinden, werden dafür Namen vergeben.
Wir sollten uns also überlegen, was wir im Skript für Variablen benötigen.
Es ist aber überhaupt kein Problem auch im nachhinein weitere Variablen zu erzeugen.
Das passiert zu Beginn des Skriptes mit dem Befehl (let*).

Code: Alles auswählen

; Teil 1 Das Script
;======================================================
(define (script-fu-hilfslinien p-Bild p-Loeschen p-anzH p-anzV)   
  (let* (       ; beginn der Variablendefinition
   
; Hier werden die Variablen definiert und mit einem Wert vorbelegt

        )       ; ende der Variablendefinition


; Hier stehen die restlichen Befehle, die sowohl die übergebenen Parameter
; wie auch die unter let* definierten Variablen benutzen können


  )            ; ende von let*
)              ; ende von define


Da wir Prozente der Bildhöhe und Bildbreite berechnen wollen, wäre es z.B. nicht schlecht die Bildhöhe und Bildbreite zu kennen und uns in Variablen zu merken sowie die berechneten Prozente.
Also könnte unser Skript z.B. so aussehen.

Code: Alles auswählen

; Teil 1 Das Script
;======================================================
(define (script-fu-hilfslinien p-Bild p-Loeschen p-anzH p-anzV)   
  (let* (               ;beginn der Variablendefinition
           (BildBreite 0)
           (BildHoehe  0)
           (TeilBreite 0)
           (TeilHoehe  0)   
        )               ; ende der Variablendefinition


; Hier stehen die restlichen Befehle, die sowohl die übergebenen Parameter
; wie auch die unter let* definierten Variablen benutzen können


  )            ; ende von let*
)              ; ende von define


Ihr seht, daß die Definition von Variablen sehr einfach ist.
Es ist nur ein Name auszudenken und ein Wert dahinter zu schreiben.
Das Ganze natürlich in Klammern eingepackt.
In unserem Fall habe ich alle Werte mit 0 vorbelegt.
Wichtig ist nur, daß die Schreibweise im gesamten Skript immer die gleiche sein muß,
denn BildBreite ist nicht bildbreite oder Bildbreite!!!

Shemesyntax
Wir wollen aber zuerst keine Hilfslinien setzen sondern sie eventuell löschen.
Aber nur "WENN" auch gelöscht werden soll.
Deshalb lernen wir jetzt den Befehl (if) zu deutsch "wenn" kennen.
Damit können wir prüfen ob eine Aussage wahr oder falsch ist, bzw. ob bestimmte Befehle abgearbeitet werden sollen oder nicht.
Wir prüfen z.B., ob wir löschen sollen.

Code: Alles auswählen

(if  (= p-Loeschen TRUE)
  (begin
               ; Block von Befehlen, die abgearbeitet werden,
               ; wenn die (wenn)-Abfrage wahr ist
  )            ; ende beginn
)              ; ende if


Zwei Dinge fallen hier auf:
  • zum einen (beginn) und
  • zum anderen, daß das Gleichheitszeichen vor den zu vergleichenden Werten liegt.
(begin ist einfach zu verstehen, hier beginnt ein Block bzw. die Folge von Befehlen, die abgearbeitet werden sollen, wenn die Aussage hinter if TRUE (wahr) ist.
Wenn wir das Häkchen in der Eingabemaske gesetzt haben, dann ist der übergebene Parameter, also p-Loeschen gleich TRUE. In diesem Fall ist die if - Abfrage wahr und der Block wird abgearbeitet.
Ist kein Häkchen gesetzt, hat der Parameter den Wert FALSE. Die if – Abfrage ist also Falsch. Der Block wird nicht abgearbeitet und das Skript überspringt den Block. Es macht erst mit dem nächsten Befehl nach der schließenden Klammer von if (;ende if) weiter.

Die zweite Frage wäre die Notation.
Skript Fu benutzt die Präfixnotation. Dabei liegt das Operationszeichen VOR den Operanden.
Die Art der Notation ist etwas gewöhnungsbedürftig, aber sehr schnell erlernbar.
Sie wird nicht nur für Vergleiche (if) angewendet, sondern für alle Aufrufe,
sei es eine Prozedur eine Aufgabe oder was auch immer.

HIER und HIER könnt ihr das noch einmal nachlesen und etwas verinnerlichen.

Prozeduren-Browser

Wir wollen jetzt vorhandene Hilfslinien Löschen.

Löschen, aber wie?

Dafür stellt GIMP eine Prozedur zur Verfügung, nur wie heißt sie?

Hier hilft uns der Prozeduren – Browser

Dort werden alle Script – Fu – Prozeduren angezeigt, sogar unsere eigenen.

Einfach mal oben den Namen unsere Prozedur eingeben, Schon sehen wir rechts, wer der Autor des Skriptes ist, wann es erstellt wurde und wie die Parameter heißen, die übergeben werden müssen.
Aber wie heißt nun unsere gesuchte Prozedur zum Löschen von Hilfslinien.

Wer, so wie ich, seine Probleme mit dem Englischen hat, oder wer nicht unbedingt alle Prozeduren durchlesen möchte, der kann zu einem einfachen Kniff greifen.
Geht einfach unter Bearbeiten auf Tastenkombinationen.
Sucht die gewünschte Funktion heraus.
Zieht das Fenster etwas breiter, so daß Ihr neben der Aktion und der Tastenkombination auch den Namen seht.
Hilfslinien löschen habe ich zwar nicht gefunden, aber unter Ansicht steht:
Ansicht /Hilfslinien anzeigen und der entsprechende Name ist "view-show-guides"
Mit view, show oder guide kann nun im Prozeduren – Browser gesucht werden.
Bei view und show haben wir keinen Erfolg, aber bei guide sieht es doch schon sehr interessant aus.
Hier finden wir 10 Einträge, die auch alle etwas mit Hilfslinien zu tun haben.

(gimp-image-add-hguide) addiert eine horizontale Hilfslinie
(gimp-image-add-vguide) addiert eine vertikale Hilfslinie

Das ist ja schon mal toll, da wir diese Funktionen später gebrauchen können.

(gimp-image-delete-guide) löscht eine Hilfslinie

Genau das, was wir gesucht haben.

Der Vollständigkeit halber noch die restlichen Prozeduren:

(gimp-image-find-next-guide) findet die nächste Hilfslinie

(gimp-image-get-guide-orientation) ermittelt die Richtung einer Hilfslinie

(gimp-image-get-guide-position) ermittelt die Position einer Hilfslinie

(script-fu-guide-new) Erzeugt eine neue Hilfslinie an Position
(script-fu-guide-new-percent) Erzeugt eine neue Hilfslinie bei x Prozent
(script-fu-guides-from-selection) Erzeugt Hilfslinien aus einer Auswahl
(script-fu-guides-removet) Löscht alle Hilfslinien

Die letzten 4 Funktionen kommen uns doch sehr bekannt vor.
Vor allem, wenn wir mal auf Bild / Hilfslinien klicken.
Genau, es sind die Funktionen, die exakt hier aufgerufen werden können.
Wir könnten sie zwar nutzen für unser Skript, aber es sind nur temporäre Funktionen,
es ist also nicht garantiert, daß sie auch noch in der nächsten GIMP-Version vorhanden sind.
Außerdem wollen wir nichts Fertiges sondern etwas Eigenes kreieren.

Wir haben jetzt eine Menge Informationen.
Manchmal muß halt nur ein wenig gesucht werden.
Und wenn das Alles nichts Hilft, kann immer noch nachgefragt werden.


Weiter oben haben wir festgestellt, daß :
(gimp-image-delete-guide) eine Hilfslinie löscht.

Die Syntax dazu ist:
(gimp-image-delete-guide image guide)

Als Parameter möchte die Prozedur also image und guide.
Das ist, wie der Beschreibung zu entnehmen ist,
zum einen das Bild und zum anderen die ID einer Hilfslinie
Das Bild haben wir ja, das ist der Parameter p-Bild,
aber wo bekommen wir denn nun wieder die ID der Hilfslinie her, die wir löschen wollen?

Da war doch noch eine Prozedur mit finden einer Hilfslinie. Sehen wir uns diese auch mal an

(gimp-image-find-next-guide image guide)

Diese Prozedur findet zwar die nächste Hilfslinie aber zuerst müssen wir mal eine haben.
Denn auch hier werden das Bild und eine Hilfslinien-ID benötigt. Ein Teufelskreis.

Doch halt unter Weitere Informationen steht ja noch eine weitere Information, nämlich die, daß wenn als guide eine 0 angegeben wird, die ID der ersten Hilfslinie zurückgegeben wird oder eine 0, falls keine Hilfslinie da ist.
Damit können wir doch etwas anfangen.

Wir brauchen zum Löschen einer Hilfslinie also zwei Befehle.
Der erste Befehl sagt uns, wie die ID der nächsten (ersten) Hilfslinie lautet und
Der zweite Befehl löscht diese Hilfslinie.
Bloß wie merken wir uns die ID der Hilfslinie?
Na klar in einer Variablen, die wir oben im (let*) Bereich schnell noch definieren.

Code: Alles auswählen

(hilfslinien-ID 0)


jetzt brauchen wir nur unsere zwei Befehle zu schreiben:

Code: Alles auswählen

(set! hilfslinien-ID (car(gimp-image-find-next-guide p-Bild 0)))
(gimp-image-delete-guide p-Bild hilfslinien-ID)


Mit (set! Variable (neuer Wert) ) weisen wir einer Variable einen neuen Wert zu.
Mit (car (Liste)) geben wir den ersten Wert einer Liste zurück.
Dazu gehe ich im nächsten Part etwas näher ein.

Diese drei Zeilen tragen wir in unser Skript und testen es gleich mal.

Code: Alles auswählen

; Teil 1 Das Script
;======================================================
(define (script-fu-hilfslinien p-Bild p-Loeschen p-anzH p-anzV)   
  (let* (                         ;beginn der Variablendefinition
           (hilfslinien-ID 0)
           (BildBreite 0)
           (BildHoehe  0)
           (TeilBreite 0)
           (TeilHoehe 0)   
         )      ; ende der Variablendefinition


; Hier stehen die restlichen Befehle, die sowohl die übergebenen Parameter
; wie auch die unter let* definierten Variablen benutzen können

(set! hilfslinien-ID (car(gimp-image-find-next-guide p-Bild 0)))
(gimp-image-delete-guide p-Bild hilfslinien-ID)


  )   ; ende von let*
)    ; ende von define


GIMP starten
Bild anlegen
Einige Hilfslinien ins Bild ziehen (auf das Lineal klicken; festhalten und aufs Bild ziehen)
Skript starten.

Zuerst Häkchen bei Löschen herausnehmen. Es sollte auch nichts passieren.
Skript wiederholen aber Häkchen setzen.

Und wer alles richtig gemacht habt, bei dem sollte eine Hilfslinie verschwinden.
Das wäre SUPER.

Jetzt starten wir das Skript so oft, bis alles Hilfslinien verschwunden sind und
Jetzt starten wir das Skript noch einmal.

Es kommt eine Fehlermeldung.
Das Skript macht schon einiges, aber es stört auch noch einiges.
Da wäre zum ersten daß es ja nur löschen soll, wenn auch was da ist, und zum anderen sollen ja ALLE Hilfslinien auf einmal gelöscht werden und nicht durch mehrmaliges aufrufen des Skriptes.

Das erste Problem könnten wir durch eine if – Abfrage lösen:

Code: Alles auswählen

(set! hilfslinien-ID (car(gimp-image-find-next-guide p-Bild 0)))
 
(if ( <> hilfslinien-ID 0)
  (begin

; nur wenn die Hilfslinien ID ungleich 0 ist,
; wenn also eine Hilfslinie vorhanden ist wird gelöscht

    (gimp-image-delete-guide p-Bild hilfslinien-ID)

  )
)


Wir können es austesten und bekommen keine Fehlermeldung mehr, wenn keine Hilfslinie mehr da ist.

Das zweite Problem kann durch eine Schleife gelöst werden. Das bedeutet, daß GIMP einen oder mehrere Befehle so lange wiederholt, bis eine bestimmte Aufgabe erfüllt ist oder bis ein bestimmter Zustand eingetreten ist.
Diese Schleife heißt "(while)", mache etwas solange, wie die Bedingung stimmt.


Code: Alles auswählen

(set! hilfslinien-ID (car(gimp-image-find-next-guide p-Bild 0)))
 
(while ( <> hilfslinien-ID 0)     ;prüfe ob eine Hilfslinie vorhanden ist
  (begin

; nur wenn die Hilfslinien ID ungleich 0 ist,
; wenn also eine Hilfslinie vorhanden ist wird gelöscht

    (gimp-image-delete-guide p-Bild hilfslinien-ID)

; Hole die nächste Hilfslinien-ID
    (set! hilfslinien-ID (car(gimp-image-find-next-guide p-Bild 0)))

  )
)


Wichtig ist, daß wir innerhalb der Schleife die nächste ID holen, denn wenn der Prüfparameter nicht angepaßt wird, kann es zu einer Fehlermeldung kommen, (hier, weil die ID nach dem Löschen ja nicht mehr existiert) oder was noch fataler ist, das Skript läuft in einer Endlosschleife und kann nur über den TaskManager (Windows) beendet werden.

Wir testen unser Skript wieder mit mehreren Hilfslinien sowohl ohne, als auch mit Häkchen und dann auch ohne Hilfslinien.
Testen ist immer sehr wichtig. Es darf ja keinen Fehler geben, auch wenn der Benutzer mal etwas Unsinniges mit dem Skript anstellt.

Nachdem wie jetzt schon eine funktionierende und getestete Löschfunktion haben,
kommen wir zum nächsten Teil. . . Dem Setzen von Hilfslinien.

Weiter oben haben wir uns ja schon die Prozeduren:
(gimp-image-add-hguide image yposition) addiert eine horizontale Hilfslinie und
(gimp-image-add-vguide image xposition) addiert eine vertikale Hilfslinie
gemerkt, die waagerechte und senkrechte Hilfslinien setzen.

Allerdings kann nur das Bild und eine Position angegeben werden.
Wie bekommen wir denn nun 25% heraus oder 10 oder 50 usw.?
Es ist wie in der Schule, wir müssen es berechnen.

Allerdings benötigen wir zuerst die Höhe und Breite des Bildes.
Mit ein wenig Sucherei im Prozeduren - Browser
finden wir auch sehr schnell die Funktionen:
(gimp-image-with image) und
(gimp-image-height image).

Die Skriptzeilen dazu müssen also so aussehen:

Code: Alles auswählen

  (set! BildBreite (car(gimp-image-width p-Bild)))
  (set! BildHoehe (car(gimp-image-height p-Bild)))


Kümmern wir uns zuerst einmal um die horizontalen Hilfslinien.
p-anzH sagt uns wie viele Linien es werden sollen.
Diese Linien sollen unser Bild gleichmäßig einteilen,
dabei entsteht immer ein Teil mehr, als Linien vorhanden sind.
Also:
1 Linie teilt das Bild in 2 Teile.
2 Linien teilen das Bild in 3 Teile.
3 Linien teilen das Bild in 4 Teile.
Usw.

Um also den genauen Abstand zwischen den einzelnen Linien zu errechnen,
müssen wir die Bildhöhe durch die um eins vermehrte Linienanzahl dividieren.
Ich weiß, daß hört sich schrecklich an, wie eine Textaufgabe in der Schule,
Aber eigentlich müssen wir nur die Linienanzahl mit 1 addieren und
die Bildhöhe durch das Ergebnis teilen.

Das sähe dann so aus:

Code: Alles auswählen

  (set! p-anzH (+ p-anzH 1))
  (set! TeilHoehe (/ BildHoehe p-anzH))


Diesen Wert geben wir jetzt in unsere Prozedur ein:

Code: Alles auswählen

 (gimp-image-add-hguide p-Bild TeilHoehe)


Das testen wir doch gleich mal:

Wir stellen verschiedene Linienanzahlen ein, auch 0.
Wie wir feststellen wird immer nur eine Linie gezeichnet.
Bei 0 aber auch.

Klar, da wir p-anzH um eins erhöhten hat es den Wert 1.
Bildhöhe geteilt durch 1 ist die Bildhöhe.
Es wird bei Bildhöhe, also an der Bildunterkante eine Hilfslinie gezeichnet.
Das könnten wir mit Hilfe der if – Anweisung aber einfach abfangen:

Code: Alles auswählen

( if (> p-anzH 1)
  (begin
    (gimp-image-add-hguide p-Bild TeilHoehe)
  )
)


Da wir aber manchmal auch mehrere Hilfslinien gezeichnet haben möchten,
ist auch hier wieder eine Schleife günstiger ergo die while – Anweisung.

Zuerst benötigen wir noch eine Variable:

Code: Alles auswählen

(zaehler 0)


Diese setzen wir auf 1

Code: Alles auswählen

(set! zaehler 1)
(while (< zaehler  p-anzH)
  (begin
    (gimp-image-add-hguide p-Bild (* TeilHoehe zaehler))
    (set! zaehler (+ zaehler 1))
  )
)


Der Zähler wurde auf 1 gesetzt.
Dann erfolgt der Vergleich mit der Linienanzahl (genauer gesagt mit der Linienanzahl +1)
Wenn der Zähler kleiner als 1 ist und das ist er ja bei Linienanzahl 4 (3+1),
dann wird eine Linie gesetzt.
Anschließend wird der Zähler um 1 erhöht auf 2.
Wieder erfolgt der Vergleich und auch 2 ist kleiner als 4.
Es wird die 2. Linie gesetzt und der Zähler auf 3 erhöht.
Wieder erfolgt der Vergleich und auch 3 ist kleiner als 4.
Es wird die 3. Linie gesetzt und der Zähler auf 4 erhöht.
Wieder erfolgt der Vergleich aber 4 ist nicht kleiner als 4, sondern gleich.
Es wird keine Linie mehr gesetzt.
Das Skript wird beendet und wir haben 3 Linien.

Zum Setzen der Linien wird in jedem Schleifendurchgang mit Hilfe des Zählers die neue Position berechnet durch die Formel TeilHoehe * Zaehler.
Beim 1. Duchgang hat der Zähler den Wert 1 * TeilHoehe (25% der Bildhöhe) = 25% der Bildhöhe
Beim 2. Duchgang hat der Zähler den Wert 2 * TeilHoehe (25% der Bildhöhe) = 50% der Bildhöhe
Beim 3. Duchgang hat der Zähler den Wert 3 * TeilHoehe (25% der Bildhöhe) = 75% der Bildhöhe

Die Linien sollten dort erscheinen, wo wir es wollten.

Unser Skript sieht bis hierher schon so aus:

Code: Alles auswählen

;**************************************************************
;* Version A ganz einfach
;**************************************************************
; Teil 1 Das Script
;======================================================
(define (script-fu-cf-tools-hilfslinien-a p-Bild p-Loeschen p-anzH p-anzV)   
  (let* (                    ;beginn der Variablendefinition
          (hilfslinien-ID 0)
          (zaehler 0)
          (BildBreite 0)
          (BildHoehe  0)
          (TeilBreite 0)
          (TeilHoehe 0)   
        )                    ; ende der Variablendefinition


; Löschen vorhandener Hilfslinien
; ===============================

; Soll wirklich gelöscht werden
(if  (= p-Loeschen TRUE)
  (begin

;Suchen der 1. Hilfslinie
    (set! hilfslinien-ID (car(gimp-image-find-next-guide p-Bild 0)))

;Prüfe ob eine  Hilfslinie vorhanden ist
    (while ( <> hilfslinien-ID 0)                     
      (begin

; nur wenn die Hilfslinien ID ungleich 0 ist,
; wenn also eine Hilfslinie vorhanden ist wird gelöscht
        (gimp-image-delete-guide p-Bild hilfslinien-ID)

; Hole die nächste Hilfslinien-ID
        (set! hilfslinien-ID (car(gimp-image-find-next-guide p-Bild 0)))

      )
    )
  )
)

; Setzen Horizontaler Hilfslinien
; ===============================
  (set! BildBreite (car(gimp-image-width p-Bild)))
  (set! BildHoehe (car(gimp-image-height p-Bild)))

  (set! p-anzH (+ p-anzH 1))
  (set! TeilHoehe (/ BildHoehe p-anzH))

; Zähler auf 1 setzen
  (set! zaehler 1)

; prüfen ob der Zähler kleiner ist als die Anzahl der Hilfslinien
  (while (<  zaehler p-anzH)
    (begin

; Wenn j, dann setze eine Hilfslinie und
      (gimp-image-add-hguide p-Bild (* TeilHoehe zaehler))

; Erhöhe den Zähler
      (set! zaehler (+ zaehler 1))
    )
  )

  )   ; ende von let*
)    ; ende von define


(script-fu-register                        ;Beginn (script-fu-register)
  "script-fu-cf-tools-hilfslinien-a"         ;Name der Funktion, die aufgerufen werden soll
  "CFU Hilfslinien Test A"                     ;Name des Skripts
  "Löscht und setzt Hilfslinien"             ;Beschreibung des Skripts
  "CF"                                        ;Name des Autors
  "Copyleft by CF"                            ;Copyright-Infos
  "11.02.2012"                                ;Datum
  "RGB* GRAY* INDEXED*"                        ;Bildtypen
  SF-IMAGE "Das Bild" 0
  SF-TOGGLE "Zuerst alle vorhandenen Hilfslinien löschen?" TRUE
  SF-ADJUSTMENT "Anzahl zu setzender Horizontaler Hilfslinien" '(3 0 50 1 10 0 0)
  SF-ADJUSTMENT "Anzahl zu setzender Vertikaler Hilfslinien" '(3 0 50 1 10 0 0)
)                                    ;Ende (script-fu-register)

(script-fu-menu-register "script-fu-cf-tools-hilfslinien-a" "<Image>/CFU/Tests")   



Testet es ausgiebig.

Bevor Ihr jetzt weiterlest, versucht doch einmal selber den Teil
für das Setzten der vertikalen Hilfslinien zu programmieren.
Und auszutesten.


So sollte es aussehen:

[spoil]

Code: Alles auswählen

; Setzen Vertikaler Hilfslinien
; =============================
(set! p-anzV (+ p-anzV 1))
(set! TeilBreite (/ BildBreite p-anzV))
(set! zaehler 1)
(while (< zaehler  p-anzV)
  (begin
    (gimp-image-add-vguide p-Bild (* TeilBreite zaehler))
    (set! zaehler (+ zaehler 1))
  )
)
[/spoil]

Das Fertige Skript sieht dann so aus:

Code: Alles auswählen

;**************************************************************
;* Version A ganz einfach
;**************************************************************
; Teil 1 Das Script
;======================================================
(define (script-fu-cf-tools-hilfslinien-a p-Bild p-Loeschen p-anzH p-anzV)   
  (let* (                    ;beginn der Variablendefinition
          (hilfslinien-ID 0)
          (zaehler 0)
          (BildBreite 0)
          (BildHoehe  0)
          (TeilBreite 0)
          (TeilHoehe 0)   
        )                    ; ende der Variablendefinition


; Löschen vorhandener Hilfslinien
; ===============================

; Soll wirklich gelöscht werden
(if  (= p-Loeschen TRUE)
  (begin

;Suchen der 1. Hilfslinie
    (set! hilfslinien-ID (car(gimp-image-find-next-guide p-Bild 0)))

;Prüfe ob eine  Hilfslinie vorhanden ist
    (while ( <> hilfslinien-ID 0)                     
      (begin

; nur wenn die Hilfslinien ID ungleich 0 ist,
; wenn also eine Hilfslinie vorhanden ist wird gelöscht
        (gimp-image-delete-guide p-Bild hilfslinien-ID)

; Hole die nächste Hilfslinien-ID
        (set! hilfslinien-ID (car(gimp-image-find-next-guide p-Bild 0)))
 
      )
    )
  )
)

; Setzen Horizontaler Hilfslinien
; ===============================
  (set! BildBreite (car(gimp-image-width p-Bild)))
  (set! BildHoehe (car(gimp-image-height p-Bild)))

  (set! p-anzH (+ p-anzH 1))
  (set! TeilHoehe (/ BildHoehe p-anzH))

; Zähler auf 1 setzen
  (set! zaehler 1)

; prüfen ob der Zähler kleiner ist als die Anzahl der Hilfslinien
  (while (<  zaehler p-anzH)
    (begin

; Wenn j, dann setze eine Hilfslinie und
      (gimp-image-add-hguide p-Bild (* TeilHoehe zaehler))

; Erhöhe den Zähler
      (set! zaehler (+ zaehler 1))
    )
  )

; Setzen Vertikaler Hilfslinien
; =============================

  (set! p-anzV (+ p-anzV 1))
  (set! TeilBreite (/ BildBreite p-anzV))
  (set! zaehler 1)
  (while (< zaehler  p-anzV)
    (begin
      (gimp-image-add-vguide p-Bild (* TeilBreite zaehler))
      (set! zaehler (+ zaehler 1))
      )
    )

  )   ; ende von let*
)    ; ende von define


(script-fu-register                        ;Beginn (script-fu-register)
  "script-fu-cf-tools-hilfslinien-a"         ;Name der Funktion, die aufgerufen werden soll
  "CFU Hilfslinien Test A"                     ;Name des Skripts
  "Löscht und setzt Hilfslinien"             ;Beschreibung des Skripts
  "CF"                                        ;Name des Autors
  "Copyleft by CF"                            ;Copyright-Infos
  "11.02.2012"                                ;Datum
  "RGB* GRAY* INDEXED*"                        ;Bildtypen
  SF-IMAGE "Das Bild" 0
  SF-TOGGLE "Zuerst alle vorhandenen Hilfslinien löschen?" TRUE
  SF-ADJUSTMENT "Anzahl zu setzender Horizontaler Hilfslinien" '(3 0 50 1 10 0 0)
  SF-ADJUSTMENT "Anzahl zu setzender Vertikaler Hilfslinien" '(3 0 50 1 10 0 0)
)                                    ;Ende (script-fu-register)

(script-fu-menu-register "script-fu-cf-tools-hilfslinien-a" "<Image>/CFU/Tests")   


Und ohne Kommentar:

Code: Alles auswählen

 (define (script-fu-cf-tools-hilfslinien-a p-Bild p-Loeschen p-anzH p-anzV)   
  (let* (                    ;beginn der Variablendefinition
          (hilfslinien-ID 0)
          (zaehler 0)
          (BildBreite 0)
          (BildHoehe  0)
          (TeilBreite 0)
          (TeilHoehe 0)   
        )                    ; ende der Variablendefinition

(if  (= p-Loeschen TRUE)
  (begin
    (set! hilfslinien-ID (car(gimp-image-find-next-guide p-Bild 0)))
    (while ( <> hilfslinien-ID 0)                     
      (begin
        (gimp-image-delete-guide p-Bild hilfslinien-ID)
        (set! hilfslinien-ID (car(gimp-image-find-next-guide p-Bild 0)))
      )
    )
  )
)

  (set! BildBreite (car(gimp-image-width p-Bild)))
  (set! BildHoehe (car(gimp-image-height p-Bild)))

  (set! p-anzH (+ p-anzH 1))
  (set! TeilHoehe (/ BildHoehe p-anzH))
  (set! zaehler 1)
  (while (<  zaehler p-anzH)
    (begin
      (gimp-image-add-hguide p-Bild (* TeilHoehe zaehler))
      (set! zaehler (+ zaehler 1))
    )
  )

  (set! p-anzV (+ p-anzV 1))
  (set! TeilBreite (/ BildBreite p-anzV))
  (set! zaehler 1)
  (while (< zaehler  p-anzV)
    (begin
      (gimp-image-add-vguide p-Bild (* TeilBreite zaehler))
      (set! zaehler (+ zaehler 1))
      )
    )

  )    ; ende von let*
)    ; ende von define

 (script-fu-register                     ;Beginn (script-fu-register)
  "script-fu-cf-tools-hilfslinien-a"         ;Name der Funktion, die aufgerufen werden soll
  "CFU Hilfslinien Test A"                 ;Name des Skripts
  "Löscht und setzt Hilfslinien"          ;Beschreibung des Skripts
  "CF"                                     ;Name des Autors
  "Copyleft by CF"                         ;Copyright-Infos
  "11.02.2012"                             ;Datum
  "RGB* GRAY* INDEXED*"                    ;Bildtypen
  SF-IMAGE "Das Bild" 0
  SF-TOGGLE "Zuerst alle vorhandenen Hilfslinien löschen?" TRUE
  SF-ADJUSTMENT "Anzahl zu setzender Horizontaler Hilfslinien" '(3 0 50 1 10 0 0)
  SF-ADJUSTMENT "Anzahl zu setzender Vertikaler Hilfslinien" '(3 0 50 1 10 0 0)
)                    ;Ende (script-fu-register)

(script-fu-menu-register "script-fu-cf-tools-hilfslinien-a" "<Image>/CFU/Tests")      



Zusammenfassung:

Wir sollten jetzt schon folgende Sheme - Befehle kennen,
die auch zu den am meisten benutzten gehören.

define
(define (prozedurname parameter1 ... parameter))
(define) definiert eine Script-Fu-Prozedur und übernimmt angegebene Parameter

let*
(let* ( (Varible Wert) ... (Varible Wert)))
Mit (let*) werden weitere Variablen definiert und mit Werten vorbelegt.

set!
(set! Variable (Neuer Wert))
Mit (set!) wird einer Variable ein neuer Wert zugewiesen

car
(car (Liste))
(car) gibt den ersten Wert einer Liste zurück.
GIMP-Prozeduren geben ihre Werte immer als Liste zurück,
selbst wenn es nur ein Wert ist z.B. (gimp-image-height).
Deshalb muß zum Auslesen von Werten einer GIMP-Prozedur
davor immer ein (car) gegeben werden.

if
(if (vergleichsoperator vergleichswert1 vergleichswert2))
Mit (if) kann eine Fallunterscheidung getroffen warden

while
(while (Wahrheitswert))
Mit (while) wird eine Schleife so lange ausgeführt,
so lange der Wahrheitswert TRUE (wahr) ist

begin
(begin Block )
Mit (beginn) wird ein Block zusammengehörender Befehle eingeklammert,
die zu if oder while gehören können.

Und von den GIMP – Prozeduren haben wir folgende kennengelernt:

(gimp-image-find-next-guide p-Bild hilfslinien-ID)
Findet die 1, oder nächste Hilfslinie

(gimp-image-delete-guide p-Bild hilfslinien-ID)
Löscht eine Hilfslinie

(gimp-image-add-hguide image yposition)
Addiert eine horizontale Hilfslinie

(gimp-image-add-vguide image xposition)
Addiert eine vertikale Hilfslinie

(gimp-image-width image)
Ermittelt die Breite eines Bildes

(gimp-image-height image)
Ermittelt die Höhe eines Bildes


Dann wüsche ich Euch noch viel Spaß beim nacharbeiten.
Und sollte etwas auf Anhieb nicht funktionieren,
nicht sofort verzweifeln.
Alles in Ruhe noch einmal nachlesen, verinnerlichen, überprüfen.
Vielleicht auch mal einen Schritt zurück gehen.
Oder einfach fragen.
(Dazu aber bitte immer das komplette Skript mit einstellen.)


Liebe Grüße
Clara

Benutzeravatar
eibauoma
Beiträge: 6003
Registriert: Do 25. Mär 2010, 21:02
Skype:
Kontaktdaten:

Re: Das bißchen Script-Fu macht sich von allein … (Part 2)

Beitragvon eibauoma » Mi 14. Mär 2012, 22:18

Hallo Clara und hallo an alle, die das auch mal testen wollen,

mich hat schon immer gestört, dass ich für einfache senkrechte und waagerechte 50 % - Hilfslinien, die man häufig benötigt, um die exakte Bildmitte zu finden, zwei verschiedene Befehle aufrufen musste.
dank der Erläuterungen von Clara zu allen Schritten hab ich zumindest verstanden, was zu tun ist. Ob ich im Einzelfall wüsste, wie ich allein zum Ergebnis komme, bezweifle ich stark.

Ich habe aber Claras Rat befolgt:
Alles in Ruhe noch einmal nachlesen, verinnerlichen, überprüfen.
Vielleicht auch mal einen Schritt zurück gehen.

Mein erstes Script funktioniert :freu:
Als Voreinstellung habe ich je 1 vertikale und horizontale Hilfslinie, nachdem eventuell vorhandene Hilfslinien gelöscht wurden.
Herzlichen Dank an Clara :dank:
Sie hat das so logisch aufgebaut, dass es gut nachzuvollziehen ist.
Damit ein paar mehr Leute Mut fassen, das auch auszuprobieren, stelle ich hier mein Script her.

edit: die scm-Datei erscheint nach dem Hochladen als Dateianhang noch nicht im Beitrag. Also bitte etwas Geduld
(Aha - im Style pro-silver bekomme ich die Fehleranzeige "Die Dateierweiterung scm ist nicht erlaubt." Bei Insist-rel hatte ich diese Fehleranzeige nicht gesehen - bitte nicht wundern, zu diesem Zeitpunkt haben wir für das Forum noch nach unserem jetzigen Style gesucht)
Deshalb kommt die Datei gezipt.
Hilfslinien.zip
(1.14 KiB) 297-mal heruntergeladen


Zurück zu „Scripte und Filter/Plugins“



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast