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
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).
Das Gimp-Perl-Handbuch verwendet Scripts, die mit folgenden Versionen getestet wurden:
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.
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:
| Wert | Bedeutung |
|---|---|
| * | jeder IMAGE-Typ wird bearbeitet |
| RGB | RGB-Bilder |
| RGBA | RGB-Bilder mit einem Alpha-Kanal |
| GREY | Bilder in Grauwertdarstellung |
| 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 |
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.
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).
Wird dieser Menüpunkt aufgerufen, erscheint folgendes Fenster:
Werden die Standardwerte bestätigt, erscheint als Ergebnis folgendes Bild:
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.
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:
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.
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:
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:
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.
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.
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() |
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: