Ein Gimp-Perl-Handbuch

© Dov Grobgeld; Last modified: 1999-06-09

Deutsche Übersetzung von Gottfried Müller

Letzte Änderungen:

19.06.1999: Ersterstellung
01.03.2000: Code-Umstellung auf XHTML 1.0, Korrekturen und Aktualisierungen, kleinere Layout-Umstellungen


0. Inhaltsverzeichnis

1. Etwas Hintergründiges

Eine der wunderbaren Eigenschaften von Gimp ist die Möglichkeit, Aufgaben durch Scripte zu lösen. Eine der bekannten Varianten bei Gimp ist die Verwendung des Scheme-Dialekts Script-Fu. Leider stellt Scheme nur eine sehr einfache Programmierung dar. So existiert unter anderem überhaupt keine Fehlerbehandlung. Außerdem müssen die Anwender mit Scheme vertraut sein. So ist es nicht verwunderlich, wenn nach anderen Kodierungen gesucht wird und diese dann eingesetzt werden, so zum Beispiel Perl für Gimp.

Perl ist eher als Sprache im Web-Umfeld zur Erstellung von CGI-Scripts und für System-Administratoren bekannt. Jetzt kann man auch Gimp-Scripte mit Perl kodieren. Dieses Handbuch will nun den Zugang zum Erstellen solcher Scripte und Plug-Ins für Gimp beschreiben.

Da es verschiedene ausgezeichnete Hand- und Lehrbücher zu Perl gibt, setzt dieses Handbuch entsprechende Kenntnisse voraus und konzentriert sich ausschließlich auf die Anwendung in Gimp zusammen mit den Perl-Modulen Gimp und Gimp::Fu, geschrieben von Marc Lehmann (email: pcg at goof.com).

2. Was brauchen wir?

Das Gimp-Perl-Handbuch verwendet Scripts, die mit folgenden Versionen getestet wurden:

  1. Gimp Version 1.04 oder höher, mit all seinen Voraussetzungen.
  2. Perl Version 5.005 oder höher.
  3. Den Perl-Modul "Gtk" Version 0.5121 oder höher.
  4. Den Gimp-Modul Version 1.083 oder höher

Perl und all die dazugehörigen Module sind in Quellform vom "Perl Comprehensive Archive Network" CPAN verfügbar oder sie können im RPM-Format vom Gimp-FTP-Server "ftp.gimp.org" bezogen werden.

3. Der Gimp-Modul

Die meisten Scripte machen Gebrauch von der vereinfachten Schnittstelle Gimp::Fu, die mit dem Gimp-Modul bereitgestellt wird. Gimp::Fu liefert ein einfaches Framework zur Parametereingabe analog zu Script-Fu mit Scheme. Es erlaubt aber auch, das Script im Batch-Mode von einer Kommandozeile auszuführen. Dieses Handbuch will dazu ausführlichere Beschreibungen bereitstellen, um Scripte auf der Basis von Gimp::Fu zu entwickeln. Bevor wir jedoch dazu übergehen, gibt es an dieser Stelle das Wesentliche zum Framework von Perl-Script-Fu.

basic.pl
1: #!/usr/bin/perl
2:
3: use Gimp;
4: use Gimp::Fu;
5:
6: # Register extension to gimp
7: register ... ;
8:
9: exit main();  # Handle over control to gimp  
   

Interessante Zeilen in diesem Script sind die Zeilen 3 und 4 für den Einsatz der beiden Module "Gimp" und "Gimp::Fu", sowie die Registrierung der Funktion (deren Einzelheiten später beschrieben werden) und die Zeile 9, um die Steuerung an Gimp zurückzugeben.

4. Die prozedurale Gimp-Datenbank (Gimp PDB)

Bevor es mit den Einzelheiten zu den Perl-Fu-Scripten weiter geht, werden wir noch etwas auf die Zugriffsmethoden der verschiedenen Funktionalitäten von Gimp eingehen. Jede Funktion, die dem Programm Gimp zur Verfügung steht, wird durch dessen prozedurale Datenbank (PDB) verwaltet. Wie der Aufruf dieser PDB-Funktionen durch Perl umgesetzt wird, ist im Weiteren zu sehen. Die PDB-Funktionen sind entweder interne Gimp-Funktionen oder sind durch ein Plug-In oder eine Script-Erweiterung entstanden. Für den Anwender exisitiert jedoch kein Unterschied im Aufruf. Wie bald zu sehen ist, wird die Perl-Funktion ebenfalls mittels der Gimp-Registrierungs-Funktion erfasst, so daß sie auch in der PDB erscheint.

Der von Gimp bereitgestellte PDB-Browser ist über das Menü Xtns->DB BROWSER erreichbar. Aus der Anzeige des Browser ist sowohl die Liste aller registrierten PDB-Funktionen zu entnehmen, als auch deren Ein- und Ausgabe-Parameter. So zeigt beispielsweise der PDB-Browser für die Gimp-Prozedur gimp_image_new zum Erzeugen eines neuen Bildes folgende Informationen an:

Name: gimp-image-new
Blurb: Creates a new Image with the specified width, height and type
In: width INT32 The width of the image
height INT32 The height of the image
type INT32 The type of image { RGB (0), GRAY (1), INDEXED (2) }

Die Funktionsbezeichner werden vom PDB-Browser im Scheme-Stil mit dem Bindestrich dargestellt. Der Perl-Programmierer muß jedoch stattdessen den Unterstrich verwenden. Damit sieht der Aufruf zum Erzeugen eines neuen RGB-Bildes der Größe 100x150 wie folgt aus:

   $img = gimp_image_new(100, 150, RGB)

Die Perl-Anweisung oben zeigt, daß gimp_image_new mit den drei Parametern Breite (width), Höhe (height) und Typ (type) aufgerufen wird. Alle Parameter sind vom Typ INT32. Dieser und alle weiteren Typangaben werden weiter unten aufgeführt und erklärt.

Für Script-Fu-Programme gibt es eine Ausnahme bei dieser Regel. Script-Fu-Programme, deren Namen in der PDB mit einem Bindestrich registriert wurden, sind mittels folgender Formulierung aufzurufen:

  gimp_call_procedure("script-fu-basic1-logo", 1, "Hello", 10,
                      "Helvetica", [0,0,0],[1,1,1]);

Unglücklicherweise hat der Autor (Dov Grobgeld) im nicht-interaktiven Betrieb Probleme. Falls ein Leser ihm helfen kann, wäre er glücklich, dies in einer neuen Handbuchversion zu modifizieren.

Hinweis !
Falls eine PDB-Funktion von Perl::Gimp aufgerufen wird, deren erste beide Argumente
vom Typ IMAGE und DRAWABLE sind, sollte nur das DRAWABLE-Argument in der
Aufrufsequenz erscheinen.

4.1. Gimp::Fu und die Registrierungsfunktion

Gimp::Fu ist die Antwort von Perl auf Script-Fu. Es liefert eine einfache Methode, um Parameter für ein Script durch die Gtk-Routinen, ähnlich zu Script-Fu, anzunehmen.

Die Hauptfunktion für ein Perl-Fu-Script ist die Registrierungsfunktion. Diese Funktion deklariert die Schnittstelle des Scriptes zu Gimp. Die Registrierungsfunktion braucht unbedingt die folgenden 10 Parameter:

  1. den Namen der Funktion vom Typ STRING, der den Bezeichner für die PDB von Gimp darstellt
     
  2. die Kurzbeschreibung vom Typ STRING
     
  3. einen Hilfetext vom Typ STRING
     
  4. den Namen des Autors vom Typ STRING
     
  5. das Script-Copyright vom Typ STRING
     
  6. das Erstellungsdatum vom Typ STRING
     
  7. den Menüpfad vom Typ STRING, der die Position in der Gimp-Menüstruktur beschreibt
    Die Pfadangabe hat eine der zwei folgenden Formen:
    1. "<Toolbox>/Xtns/Perl-Fu/script-Name"
    2. "<Image>/Perl-Fu/Script-Name"
    Die 1. Form ist zu verwenden, falls das Script seine Eingaben nur durch das Gimp-Perl-Interface bezieht (und kein aktuelles Bild benötigt). Die 2. Form wird benötigt, wenn das Script über das Popup-Menü erscheinen soll (rechte Maus-Taste über dem aktuellen Bild). In diesem Fall übergibt Gimp::Fu als erste zwei Parameter dem Script die aktuelle IMAGE- und DRAWABLE-Information, wenn es aufgerufen wird.
     
  8. die Liste der akzeptierten Bildformate (als STRING-Typ), die vom Script bearbeitet werden können. Sie ist nur erforderlich, wenn das Script im Popup-Menü eingehängt wurde. Zulässige IMAGE-Typ-Werte sind:
    Wert Bedeutung
    * jeder IMAGE-Typ wird bearbeitet
    RGB RGB-Bilder
    RGBA RGB-Bilder mit einem Alpha-Kanal
    GREY Bilder in Grauwertdarstellung

     
  9. Beschreibung eines Eingabe-Parameterfeldes (in Perl wird eine solche Struktur in eckigen Klammern kodiert). Jeder Parameter ist in sich selbst wieder ein Parameterfeld, das wiederum vier oder fünf Werte enthalten kann:
    1. Der Typ des Parameters. Die Typen sind von Gimp::Fu vorgegeben und werden in der nachstehenden Tabelle aufgeführt.
    2. Der Name des Parameters (STRING)
    3. Ein Hilfetext zum Parameter
    4. Den Standardwert des Parameters
    5. Ein Feld, welches den zulässigen Wertebereich definiert. Diese Angabe ist nur für PF_SLIDER und PF_SPINNER.
    Typ mögliche Angaben Bemerkung
    PF_INT
    PF_INT32
    PF_INT16
    PF_INT8
    42 ganze Zahl; PF_INT ist ein Synonym für PF_INT32
    PF_VALUE
    PF_FLOAT
    3.141 Gleitkommazahl
    PF_TOGGLE
    PF_BOOLEAN
    0
    1
    logischer Wert
    PF_SLIDER
    PF_SPINNER
    [0,100,1] Parameterfeld mit Minimum, Maximum und Schrittweite
    PF_FONT -*-blippo-*-*-*-*-24-*-*-*-*-*-*-* Fontangabe im X11-Format (aktiviert Font-Browser)
    PF_STRING "Eine Zeichenkette"  
    PF_COLOR
    PF_COLOUR
    [255,127,0]
    #FF7F00
    Farbangabe als Dezimal-Tripel oder Hexakette
    PF_IMAGE   IMAGE-Parameter
    PF_DRAWABLE   DRAWABLE-Parameter
    PF_BRUSH   BRUSH-Parameter
    PF_GRADIENT   GRADIENT-Parameter
    PF_PATTERN   PATTERN-Parameter

     
  10. Beschreibung eines Ausgabe-Parameterfeldes des Unterprogrammaufrufes für den nachfolgenden Parameter
     
  11. eine Angabe zu einem Unterprogramm (sub), das aktiviert werden soll, wenn die entsprechende Angabe in der Menüstruktur angeklickt wurde. Dabei wird dem Unterprogramm die Liste der Parameter übergeben, die im 9. Parameterfeld beschrieben werden. Ist das Script im Popup-Menü ("<Image>...") verankert, werden zwei Parameter (IMAGE und DRAWABLE) vor diesen Parametern eingefügt.
    Eine Verweisangabe auf ein Unterprogramm kann in Perl auf zweierlei Wegen erfolgen. Entweder durch eine Definition des Unterprogramms an einer anderen Stelle im Quellscript. Heißt das Unterprogramm zum Beispiel "run", ist "\&run" zu kodieren. Als Alternative kann auch eine Inline-Kodierung erfolgen in der Form:
        sub { ($text, $color) = @_ ; ... }
    	
    Vom Unterprogramm wird nicht erwartet, daß es das neu erzeugte Bild selbst darstellt. Stattdessen wird das Bild oder auch mehrere Bilder entsprechend den Angaben des 10. Parameters zurückgeliefert werden. Mehr darüber folgt weiter unten.

4.2. Ein kommentiertes Script

Das folgende Beispiel eines Perl-Fu-Scriptes zeigt die Schritte, die oben beschrieben wurden. Es registriert ein Script, welches zwei Parameter benötigt, die Bildgröße und eine Farbe. Es generiert ein Bild in der angegeben Größe und Farbe. Das Script ist nicht weiter aufregend, zeigt jedoch die wichtigsten Schritte zur Registration, zur Bilderzeugung und wie auf einige PDB-Funktionen zugegriffen wird.

uni.pl
 1: #!/usr/bin/perl -w
 2:
 3: use Gimp;
 4: use Gimp::Fu;
 5:
 6: sub img_uni {
 7:     my ($size, $color) = @_;
 8:
 9:     # Create a new image
10:     $img = Gimp->gimp_image_new($size, $size, RGB);
11: 
12:     # Create a new layer
13:     $layer = Gimp->gimp_layer_new($img, $size, $size, RGB,
14:                        "Layer 1", 100, NORMAL_MODE);
15:
16:     # Add the layer to the image
17:     Gimp->gimp_image_add_layer($img, $layer, -1);
18:
19:     # Set the background to the required color
20:     Gimp->gimp_palette_set_background($color);
21:
22:     # Paint the layer
23:     Gimp->gimp_edit_fill($layer);
24:
25:     # Return the image
26:     return $img;
27: }
28:
29: register
30:     "img_uni",                 # fill in name
31:     "Create a uniform image",  # a small description
32:     "A tutorial script",       # a help text
33:     "Dov Grobgeld",            # Your name
34:     "Dov Grobgeld (c)",        # Your copyright
35:     "1999-05-14",              # Date
36:     "<Toolbox>/Xtns/Perl-Fu/Test/Img Uni...",   # menu path 
37:     "*",                       # Image types
38:     [
39:      [PF_INT,   "size", "Img size", 100],
40:      [PF_COLOR, "color", "Img color", [255,127,0]]
41:     ],
42:     \&img_uni;
43:
44:exit main();
   

Dieses Script zeigt die typischen Schritte bei der Entwicklung eines solchen Programms:

Um das Script zu testen, ist es im Verzeichnis $HOME/.gimp/plug-ins zu speichern und dann Gimp zu starten. Es ist eine ausgesprochen gute Idee, die Syntax des Scriptes mit perl -c zu überprüfen, bevor Gimp gestartet wird.

Der eigentlich korrekte Weg, ein Script in ein Gimp-Verzeichnis einzutragen, ist der Befehl gimptool mit den Varianten:

  # Ablegen im lokalen Anwenderverzeichnis
  gimptool --install-bin <scriptname>

  # oder Ablegen im globalen Systemverzeichnis (nur als Administrator)
  gimptool --install-admin-bin <scriptname>

Hinweis: In älteren Gimp-Versionen ist es durchaus möglich, daß während der Programmausführung ein Scipt nicht registriert werden kann. Deshalb ist nach der Script-Speicherung im angegebenen Verzeichnis Gimp erneut zu starten. Ist das Script bereits registriert, kann ohne erneute Registrierung (vorausgesetzt die Parameterstruktur hat sich nicht geändert) das Script modifiziert werden.

Das Script ist nun über das Menüsystem des Werkzeugfenster erreichbar (Xtns).

uni menu

Wird dieser Menüpunkt aufgerufen, erscheint folgendes Fenster:

unit entry

Werden die Standardwerte bestätigt, erscheint als Ergebnis folgendes Bild:

uni result

5. Objektorientierter Syntax

Gimp::Fu stellt auch einen alternativen objektorientierten Ansatz der Kommandos zur IMAGE- und DRAWABLE-Bearbeitung bereit. In der folgenden Tabelle sind als Beispiel ausgewählte Kommandos in prozeduralen und objektorientierten Syntax gegenübergestellt.

Prozedurale Syntax Objektorientierte Syntax
  gimp_image_add_layer($drw,-1);     $img->add_layer($drw, -1);  
  gimp_drawable_width($drw);     $drw->width();  

Die Regeln, um eine PDB-Funktion in die entsprechende objektorientierte Bezeichnung zu konvertieren, ist relativ einfach. PDB-Funktionen, die mit "gimp_image_" beginnen, werden durch das "$img"-Objekt ersetzt. Analoges gilt für die PDB-Funktionen, die mit "gimp_drawable_" beginnen. Diese werden durch das "$drw"-Objekt ersetzt.

Es ist an dieser Stelle zu bemerken, daß die objektorientierte Syntax nur eine schmackhafte Beigabe ist, um die Aufruf-Syntax in einigen Fällen verständlicher zu gestalten. Fehlermeldungen sind jedoch weiterhin den prozeduralen Gesetzen unterworfen.

6. Selektionen im Bildbereich

Im Script "uni" wurde die Funktion gimp_edit_fill verwendet, um das gesamte Bild mit der Hintergrundfarbe zu füllen. Sieht man sich im PDB-Browser die Information zu dieser Funktion an, wird man folgends finden:

Name: gimp-edit-fill
Blurb: Fill selected area of drawable
In: drawable DRAWABLE The drawable fill from

Wie Sie sicherlich bemerkt haben, ist in Gimp-Perl kein IMAGE-Parameter angegeben, da er automatisch als Parameter hinzugefügt wurde.

Wird gimp_edit_fill mit einem selektierten Bildbereich aufgerufen (durch die DRAWABLE-Information beschrieben), dann wird die Funktion nur in der Selektion wirksam. Es gibt jede Menge Möglichkeiten, eine Selektion auszuwählen. Man kann sich schnell darüber eine Vorstellung verschaffen, indem man sich im PDB-Browser alle Funktion suchen läßt, die die Zeichenkette 'select' enthalten. So kann man zum Beispiel von der Funktion gimp_rect_select folgende Informationen erhalten:

Name: gimp-rect-select
Blurb: Create a rectangular selection over the specified image
In: image IMAGE The image
x FLOAT x coordinate of upper-left corner of rectangle
y FLOAT y coordinate of upper-left corner of rectangle
width FLOAT the width of the rectangle: 0 < width
height FLOAT the height of the rectangle: 0 < height
operation INT32 the selection operation: {ADD (0), SUB (1), REPLACE (2), INTERSECT (3) }
feather INT32 feather option for selections
feather_radius FLOAT Radius for the feather operation

Eine einfache Anwendung dieser Funktion stellt das folgende Script dar. Dabei wird in der Mitte des Bildes ein Rechteck ausgewählt und mit einer anwenderdefinierten Farbe gefüllt. Außerdem zeigt das Beispiel weitere neue Funktionalitäten an, die noch nicht behandelt wurden:

paint-select.pl
 1: #!/usr/bin/perl -w 
 2: 
 3: use Gimp; 
 4: use Gimp::Fu; 
 5: 
 6: register 
 7:     "img_paint_select", 
 8:     "Paints the selection", "Paints the selection", 
 9:     "Dov Grobgeld", "Dov Grobgeld", "1999-05-14",  
10:     "<Image>/Perl-Fu/Test/Paint Select...",  
11:     "*",  
12:     [ 
13:      [PF_COLOR, "color", "Rectangle color", [0,0,255]] ], 
14:     sub { 
15:         my($img, $layer, $color) = @_; 
16:         my($width, $height) = (Gimp->gimp_image_width($img), 
17:                                Gimp->gimp_image_height($img)); 
18: 
19:         print "img width heigh = $img ($$img) $width $height\n"; 
20:         # Select a rectangle inside the image and paint it with color 
21:         Gimp->gimp_undo_push_group_start($img); 
22:         Gimp->gimp_rect_select($img, 
23:                          $width/4, $height/4, $width/2, $height/2, 
24:                          REPLACE, 0, 0); 
25:         Gimp->gimp_palette_set_background($color); 
26:         Gimp->gimp_edit_fill($layer); 
27:         Gimp->gimp_selection_none($img); 
28:         Gimp->gimp_displays_flush(); 
29:         Gimp->gimp_undo_push_group_end($img); 
30:  
31:         # Tell gimp not to display a new image 
32:         return (); 
33:     }; 
34:  
35: exit main();
   

Hier ist das Ergebnis, wenn das Script auf unser vorangegangenes Bild angewendet wird:

paint select

6.1. Komplexe Bildselektionen

Neben der rechteckigen Bildauswahl existieren weitere umfangreichere Varainten der Bildauswahl. So sind elliptische Bildselektionen mittels der Funktion gimp_ellipse_select() und eine Freihandauswahl über die Funktion gimp_free_select() realisierbar.

Weitaus komplexere Selektionen sind über die Bildkanäle zu gestalten. Die PDB-Funktion gimp_channel_new() erzeugt einen neuen Kanal (chanel). Kanäle stellen ebenfallls Zeichenebenen dar, die jedoch im Gegensatz zu den bisherigen Zeichenebenen (drawables) nur eine Grauwertdarstellung repräsentieren. Ist die Arbeit in einem solchen Kanal beendet, kann das Ergebnis durch die PDB-Funktion gimp_selection_load() in den ausgewählten Bildbereich übernommen werden.

An dieser Stelle gibt es nochmals den Hinweis, daß die Suchfunktion im PDB-Browser zum Begriff "select" alle Funktionen liefert, die mit einer Bildauswahl im Zusammenhang stehen.

6.2. Schleifen

In Perl ist es einfach, Schleifen zu kodieren, und im Zusammenhang mit den Auswahlwerkzeugen verblüffende Resultate zu generieren. Hier folgt ein Beispiel, in dem Farben in Kreisen gemischt werden. Das ist zwar nichts Neues, zeigt aber die Stärke der obengenannten Strukturen:

circles.pl
 1: #!/usr/bin/perl 
 2: 
 3: use Gimp; 
 4: use Gimp::Fu; 
 5: 
 6: sub circles { 
 7:     my ($size, $bgcolor, $radius) = @_; 
 8:    
 9:     # Create the background 
10:     $img = Gimp->gimp_image_new($size, $size, RGB); 
11:     $layer = Gimp->gimp_layer_new($img, $size, $size, RGB, 
12:                            "Layer 1", 100, NORMAL_MODE); 
13:     Gimp->gimp_image_add_layer($layer, -1); 
14:     Gimp->gimp_palette_set_background($bgcolor); 
15:     Gimp->gimp_edit_fill($layer); 
16: 
17:     my $ncircles = int($size/$radius/2); 
18:     
19:     for ($i=0; $i<$ncircles; $i++) { 
20:         for ($j=0; $j<$ncircles; $j++) { 
21:             # Be creative and mix colors 
22:             $color = [$i*30, ($ncircles-$j)*25, ($i+$j)*15]; 
23: 
24:             # Select a circle 
25:             Gimp->gimp_ellipse_select($img, 
26:                                 $i*$radius*2, $j*$radius*2, 
27:                                 $radius*2, $radius*2, 
28:                                 REPLACE, 1, 0, 0); 
29: 
30:             # Paint the color in the circle 
31:             Gimp->gimp_palette_set_background($color); 
32:             Gimp->gimp_edit_fill($layer); 
33:             Gimp->gimp_selection_none($img); 
34:         } 
35:     } 
36: 
37:     return $img; 
38: } 
39: 
40: # register the script 
41: register "circles", "a loop", "a loop", "Dov", "Dov", "1999-05-14", 
42:     "<Toolbox>/Xtns/Perl-Fu/Test/Circles...",  
43:     "*", 
44:     [ 
45:      [PF_INT32, "size", "Img size", 100], 
46:      [PF_COLOR, "bg", "Background color", [40,180,60]], 
47:      [PF_INT32, "radius", "Circle radius", 10] 
48:     ], 
49:     \&circles; 
50: 
51: exit main();
   

Hier ist das Ergebnis:

circles

7. Text erzeugen

7.1. "Hello World" - Text in ein Bild schreiben

Um ein Text zu erzeugen, kann die Funktion gimp_text_fontname verwendet werden. In dieser Funktion ist der Font in der X11-Notation anzugeben. (Es gibt noch einige ältere Funktionen wie gimp_text oder gimp_text_ext, die hier abweichende Eingaben einsetzen.)

Im folgenden Beispiel ist das unvermeidbare "Hello World" zu sehen:

hello-world1.pl
 1: #!/usr/bin/perl 
 2: 
 3: use Gimp; 
 4: use Gimp::Fu; 
 5: 
 6: sub text1 { 
 7:     my($font, $text) = @_; 
 8:     
 9:     # Create a new image 
10:     $img = Gimp->gimp_image_new(350, 100, RGB); 
11: 
12:     # Create a new layer and draw it to the image at the top 
13:     $drw = Gimp->gimp_layer_new($img, $img->width, $img->height, 
14:                           RGB, "BG", 100, NORMAL_MODE); 
15:     $drw->add_layer(-1); 
16:     Gimp->gimp_palette_set_background("black"); 
17:     Gimp->gimp_edit_fill($drw); 
18: 
19:     # Choose color of text 
20:     Gimp->gimp_palette_set_foreground([255,255,0]); 
21: 
22:     # Create the text 
23:     my $border = 10; 
24:     my $text_layer = Gimp->gimp_text_fontname($drw,  0, 0, $text, 
25:                                        $border, 1,  
26:                                        xlfd_size($font), $font); 
27:     Gimp->gimp_floating_sel_anchor($text_layer); 
28:     
29:     return $img; 
30: } 
31: 
32: # register the script 
33: register "hello_world1", "basic text", "basic text", "Dov", "Dov", 
34:     "1999-05-14", 
35:     "<Toolbox>/Xtns/Perl-Fu/Test/Hello World1...",  
36:     "*", 
37:     [ 
38:      [PF_FONT, "font", "font", "-*-blippo-*-*-*-*-80-*-*-*-*-*-*-*"], 
39:      [PF_STRING, "text", "text", "Hello world!"] 
40:     ], 
41:     \&text1; 
42: 
43: # Handle over control to gimp 
44: exit main();
   

Hier das Ergebnis:

hello world 1

Das Script verwendet die Funktion xlfd_size, das die Schriftgröße des Fonts ermittelt. Das ist deshalb notwendig, weil der Autor der Funktion gimp_text_fontname sich dafür entschieden hat, die Größenangabe im Fontname zu ignorieren.

Es ist noch darauf hinzuweisen, daß in Zeile 24 des Scriptes beim Erzeugen des Textes eine Arbeitsebene generiert wird ("floating selection" = schwebende Auswahl), die noch unbedingt durch die Funktion gimp_floating_sel_anchor verankert werden muß (Zeile 27).

Dem Script hängt noch ein Problem an: die Bildgröße und die Textabmessungen stehen in einem ungünstigen Verhältnis zueinander. Diesem Gesichtspunkt wird im nachfolgenden Script mehr Rechnung getragen. Es zeigt die grundlegenden Schritte, die notwendig sind, um das Problem in geeigneter Weise zu lösen.

Als Ergebnis entsteht ein Bild aus zwei Ebenen, einer transparenten Textebene, die über einer einfarbigen Hintergrundebene liegt.

basic-logo.pl
 1: #!/usr/bin/perl 
 2:  
 3: use Gimp; 
 4: use Gimp::Fu; 
 5:  
 6: sub basic_logo { 
 7:     my($font, $border, $text, $bgcolor, $fgcolor) = @_; 
 8:  
 9:     # Create a new image of an arbitrary size with  
10:     $img = Gimp->gimp_image_new(100, 100, RGB); 
11:      
12:     # Create a new layer for the background of arbitrary size, and 
13:     # add it to the image 
14:     my $background = Gimp->gimp_layer_new($img, 100, 100, 
15:                                RGB, "Background", 100, 
16:                                NORMAL_MODE); 
17:     Gimp->gimp_image_add_layer($background, 1); 
18:  
19:     # Choose color of text 
20:     Gimp->gimp_palette_set_foreground($fgcolor); 
21:  
22:     # Create the text layer. Using -1 as the drawable creates a new layer. 
23:     my $text_layer = Gimp->gimp_text_fontname($img, -1, 0, 0, $text, 
24:                                    $border, 1, 
25:                                    xlfd_size($font), $font); 
26:  
27:     # Get size of the text drawable and resize the image and the 
28:     # background layer to this size. 
29:     my($width, $height) = ($text_layer->width, $text_layer->height); 
30:     Gimp->gimp_image_resize($img, $width, $height, 0, 0); 
31:     Gimp->gimp_layer_resize($background, $width, $height, 0, 0); 
32:  
33:     # Fill the background layer now when it has the right size. 
34:     Gimp->gimp_palette_set_background($bgcolor); 
35:     Gimp->gimp_edit_fill($background); 
36:      
37:     return $img; 
38: } 
39:  
40: # register the script 
41: register "basic_logo", "basic logo", "basic logo", 
42:     "Dov Grobgeld", "Dov Grobgeld", 
43:     "1999-06-09", 
44:     "<Toolbox>/Xtns/Perl-Fu/Test/Basic Logo...", 
45:     "*", 
46:     [ 
47:      [PF_FONT,   "font",     "font",   "-*-blippo-*-*-*-*-70-*-*-*-*-*-*-*"], 
48:      [PF_INT,    "border",   "border", "10"], 
49:      [PF_STRING, "text",     "text", "Hello world!"], 
50:      [PF_COLOR,  "bg_color", "Background color", [40,180,160]], 
51:      [PF_COLOR,  "fg_color", "Background color", [255,255,0]], 
52:     ], 
53:     \&basic_logo; 
54:  
55: # Handle over control to gimp 
56: exit main();

Ein besonderes Augenmerk im Script "basic-logo" gilt der Funktion gimp_image_text_fontname() in der Zeile 23. Sie verlangt im ersten Argument das Bild und im zweiten Argument eine Zeichenebene (drawable), die hier den Wert -1 zugewiesen bekommt. Das steht im direkten Widerspruch zu der weiter oben genannten Regel, daß das Bildargument (image) nicht anzugeben ist, wenn sowohl ein Bild und eine Zeicheneben die ersten beiden Argumente darstellen. Da jedoch der Wert für die Zeichenebene -1 und kein Bild zugeordnet ist, muß ein Bildparameter explizit angegeben werden. In diesem Fall bedeutet die Angabe -1 für die Zeichenebene, daß statt der temporären Zeichenebene ("floating selection" = schwebende Auswahl), eine neue Bildebene angelegt wird.

Das in der nachfolgenden Abbildung gezeigte Ergebnis ist zufriedenstellender als das vorherige Resultat.

basic logo dialog
basic logo

8. "Floating selection" - Die schwebende Auswahl

Wird ein Bereich durch eine der Selektionsroutinen markiert und ist durch eine umlaufende Linie gekennzeichnet, kann dieser Bereich in die Zwischenablage durch die Funktion gimp_edit_copy kopiert werden. Aus diesem Zwischenspeicher kann dann mehrmals diese Information in verschiedene Ebene über die Funktion gimp_edit_paste eingefügt werden. Ist eine Ebene auf diese Art und Weise modifiziert worden, ist das Ergebnis in der "floating selection" (= schwebende Auswahl), der temporären Arbeitsebene zu finden. Die noch nicht endgültige Kopie kann in ihrer Lage über die Funktion gimp_layer_set_offsets noch verschoben werden, bevor sie dann mit der Funktion gimp_floating_sel_anchor in die eigentliche Arbeitsebene verankert wird.

Eine andere Methode, die Einfügeposition festzulegen, ist eine Selektion in der Zielebene zu erzeugen, bevor der Zwischenspeicher eingefügt wird.

Das wird im folgenden Programm veranschaulicht. Es verknüpft ein Bild mit einem anderen Bild. Die Zeilen 28-38 zeigen, wie das zweite Bild kopiert und auf das erste Bild geklebt wird.

horiz-cat.pl
 1: #!/usr/local/bin/perl 
 2:  
 3: use Gimp qw( :auto ); 
 4: use Gimp::Fu; 
 5: 
 6: sub horiz_cat { 
 7:     my($img1, $drw1, $drw2) = @_; 
 8: 
 9:     # Get image 2 
10:     $img1 = $drw1->image(); 
11:     
12:     my $img2 = gimp_drawable_image($drw2); 
13:     
14:     # Get sizes through OO syntax 
15:     my($w1, $h1) = ($drw1->width, $drw1->width); 
16:     my($w2, $h2) = ($drw2->width, $drw2->height); 
17: 
18:     # The new height is the maximum height of the images 
19:     my $hmax = $h1 > $h2 ? $h1 : $h2; 
20: 
21:     # Create an undo group 
22:     gimp_undo_push_group_start($img1); 
23:     
24:     # Resize the drawable layer to make room for the img 
25:     gimp_image_resize($img1, $w1+$w2, $hmax, 0, ($hmax-$h1)/2); 
26:     gimp_layer_resize($drw1, $w1+$w2, $hmax, 0, ($hmax-$h1)/2); 
27: 
28:     # Copy $drawable2 and paste it into the new space of $drawable1 
29:     # select all of img2 
30:     gimp_selection_all($img2); 
31: 
32:     # copy it to the clipboard 
33:     gimp_edit_copy($drw2); 
34: 
35:     # make a selection in img 1 in the position where it is to be pasted 
36:     gimp_rect_select($img1, $w1, ($hmax-$h2)/2, $w2, $h2, 0,0,0); 
37: 
38:     # paste and then anchor it 
39:     my $floating_layer = gimp_edit_paste($drw1, 0); 
40:     gimp_floating_sel_anchor($floating_layer); 
41: 
42:     # Close the undo group 
43:     gimp_undo_push_group_start($img1); 
44:     
45:     # Update the display 
46:     gimp_displays_flush(); 
47:     
48:     return undef; 
49: } 
50: 
51: # register the script 
52: register "horiz_cat", "Horizontal concat", "Horizontal Concat", 
53:     "Dov Grobgeld", "Dov Grobgeld", 
54:     "1999-05-4", 
55:     "<Image>/Perl-Fu/Test/Horizontal Concat",  
56:     "*", 
57:     [ 
58:      [PF_DRAWABLE,   "drawable",     "Drawable to concatinate",   undef], 
59:     ], 
60:     \&horiz_cat; 
61: 
62: # Handle over control to gimp 
63: exit main(); 
   

9. Der Perl-Server und Stand-alone-Scripts

Alle bisherigen Scripte wurden innerhalb der Menüstruktur gestartet. Aber es gibt noch eine andere Möglichkeit. Sie besteht darin, die Scripte von der Kommandozeile als normales Perl-Programm aufzurufen. In diesem Fall versucht das Script eine Verbindung zum Perl-Server herzustellen. Schlägt diese Aktion fehl, startet das Script Gimp selbst. Sollen gleichzeitig mehrere solche Scripte laufen, ist es effizienter und sicherlich auch schneller, wenn der Perl-Server von Gimp aus gestartet wird (Xtns-Menü im Werkzeugfenster).

Läuft ein Perl-Fu-Script von der Kommandozeile aus, agiert das Script genau so als wenn es von einem Menüpunkt ausgerufen wurde. Einzige Ausnahme ist die Angabe des Aufrufarguments --output. In diesem Fall erfolgt die Ausgabe des Ergebnisses in eine Datei (anstelle das Bild anzuzeigen). Dieses Batch-Verfahren eignet sich besonders um Logos oder ähnliches zu erzeugen.

Der Dateiname zum --output-Argument hat das gleiche Verhalten wie es auf den Manual Pages von "Gimp::Fu" beschrieben ist (z.Bsp. eine Interlace-Ausgabe).

Zu bemerken ist, daß alle Regeln zu den Bildern und Dateien weiterhin gültig sind. Das bedeutet zum Beispiel, wenn ein Bild als eine GIF-Datei abgespeichert werden soll, muß es vom RGB-Format in ein Index-Format konvertiert werden. Zur Zeit ist es noch in jedes Script einzufügen. Aber vielleicht ist es in einer zukünftigen Gimp::Fu-Version möglich, das als eine Option einzubinden.

Hier sind zwei Batch-Aufrufe von Scripten, die bereits weiter oben deklariert wurden, jedoch mit dem gesetzten Output-Flag, um entweder eine Datei im JPG-Format bzw. im PNG-Format zu erzeugen. Eine Speicherung im GIF-Format, ist wie bereits gesagt, nur dann möglich, wenn das Bild in ein Index-Format überführt wurde.

   1: uni -o /tmp/uni.png -size 100 -color "#5050ff"
   2: basic-logo -o /tmp/bl.jpg -text "Perl rules"

Ein anderer wichtiger Aspekt, um diese Schnittstelle zu nutzen, ist die Möglichkeit den Perl-Debugger einzusetzen, um die Perl-Fu-Scripts zu testen.

Hinweis: Die Bilddateien werden in das Verzeichnis gesichert, von dem aus Gimp gestartet wurde und nicht in das Verzeichnis, von dem das Gimp-Perl-Script aufgerufen wurde.

9.1. Eine Shell für Gimp-Perl

Falls der Perl-Server verwendet wird, ist es nicht notwendig, Gimp::Fu und die Registrierungs-Funktion einzusetzen. Stattdessen ist Gimp::Net und das Unterprogramm (sub) mit dem Namen net zu verwenden.

Als ein einfaches aber doch mächtiges Beispiel zum Einsatz von Gimp ohne Fu ist hier eine interaktive Gimp-Perl-Shell, die von der Kommandozeile aufgerufen werden kann.

pg-shell.pl
 1: #!/usr/bin/perl 
 2: 
 3: use Gimp; 
 4: use Term::ReadLine; 
 5: 
 6: sub net { 
 7:     $term = new Term::ReadLine; 
 8:     while( defined ($_ = $term->readline("Gimp> "))) { 
 9:         $res = eval($_) . "\n"; 
10:         print("Error: $@"), next if $@; 
11:         print "\n"; 
12:     } 
13: } 
14: 
15: exit Gimp::main(); 
16:
   

Und hier ist ein Beispiel für eine interaktive Session mit dieser Shell:

interact.txt

1: Gimp> $img = gimp_image_new(100,100,RGB) 
2: Gimp> $drw = $img->layer_new(100,100,RGB_IMAGE, "bg", 100, NORMAL_MODE) 
3: Gimp> $img->add_layer($drw,-1) 
4: Gimp> $img->display_new 
5: Gimp> $drw->edit_fill 
6: Gimp> gimp_displays_flush()
   

10. Schlußbemerkungen

Dieses Handbuch deckt nur einen kleinen Teil der Möglichkeiten ab, die sich für einen Script-Entwickler bieten. So sind zum Beispiel folgende Gestaltungsmöglichkeiten in Gimp-Perl-Scripten verfügbar, die hier nicht behandelt wurden:

11. Links und Referenzen


Senden Sie bitte Ihre Hinweise in englischer Sprache an den Autor des Originaldokuments dov at imagic.weizmann.ac.il oder an den deutschen Übersetzer gmueller at gm4t9.de

Valid XHTML 1.0!