CHAPITRE 43


Script-Fu

SCRIPT-FU

ECOLE DE SCRIPT-FU NIVEAU CEINTURE NOIRE DE MIKE’S





GIMP CHAPITRE 43


L’école de Script-Fu de Mike Terry

Auteur Mike Terry


LE CHEMIN DE LA MAITRISE DE SCRIPT-FU


Ainsi, petit bizut, tu as trouvé Gimp, et tu veux apprendre certains de ses secrets ?

Plus précisément, vous voulez apprendre à vous servir de ses fantastiques possibilités de script, n’est-ce pas ? Vous êtes peut-être tenté par la perspective d’une fastidieuse édition automatique d’images, ou peut-être vous demandez-vous seulement le niveau de précision de votre travail que seul un script bien écrit peut permettre d’obtenir....

Eh bien, vous avez frappe à la bonne porte, mon ami, car l’école de Script-Fu de la ceinture noire Mike Terry pourra vous entraîner à l’art moins ancien du Script-Fu.


SURVOL DU PROGRAMME (COURSE OUTLINE)

Dans le programme d’apprentissage, nous vous ferons connaître l’essentiel de Schème nécessaire pour utiliser Script-Fu, puis nous vous ferons construire un script maniable que vous pourrez ajouter à votre boite à outils de scripts. Ce script donne des suggestions à l’utilisateur pour du texte, puis crée une image parfaitement dimensionnée pour ce texte. Nous améliorerons ce script pour permettre une marge (buffer) ou espace autour du texte.


Faites connaissance avec votre instructeur

Je d’abord avouer n’être qu’une ceinture jaune dans cet art, et que je ne puis donc vous amener qu’à ce niveau. Cependant, à nous deux nous pourrons nous appuyer l’un sur l’autre et nous élever plus haut. Si je me trompe, si j’oublie un détail important ou si je me trompe complètement, merci de m’envoyer un courriel pour me permettre de corriger. De même, si vous avez des conseils ou des suggestions sur la façon d’améliorer cet entraînement, envoyez les moi s’il vous plaît.

J’espère que vous profiterez de cet apprentissage, et puissiez-vous devenir bientôt un maître du Script-Fu!


Public concerné

Ce programme d’entraînement est destine aux débutants en Script-Fu. Quand j’ai appris que Gimp permettait les scripts, j’ai été très intéressé, et j’ai cherché à approfondir le sujet. Malheureusement, les instructions étaient peu abondantes et limitées, particulièrement quand on ne connaissait pas Schème (ce qui était mon cas). Après avoir passé environ deux jours à tenter de faire rentrer en force la cheville carrée de mes connaissances de C++ dans le trou rond de Schème, j’ai calculé qu’un didacticiel fait à partir des bases, plein comme un œuf d’exemples, serait très utile au débutant en Script-Fu. En principe, ce didacticiel est donc prévu pour les débutants, mais comme j’ai appris depuis de nouvelles choses, je l’ai étendu pour vous permettre de tous devenir des maîtres du Script-Fu! Vos suggestions et critiques sont les bienvenues:

Michael Terry

mterry@soulfry.com


LEÇON 1: APPRENDRE A CONNAÎTRE SCHEME


AVANT DE COMMENCER...

Avant de commencer, il faut nous assurer que nous sommes dans le même dojô. C’est à dire que vous devez avoir Gimp installé et complètement fonctionnel. Pour obtenir la dernière version de Gimp, ou pour l’installer et le lancer, allez à la page d’accueil principale de Gimp. (Ce guide d’apprentissage a été rédigé pour Gimp 1.0.0.)


COMMENÇONS A SCHEME’R

La première chose à apprendre est celle-ci:

Chaque instruction de Schème est entourée par des parenthèses ().

La seconde chose qu’il vous faut savoir est que :

La fonction nom/opérateur est toujours la première partie dans les parenthèses, les autres parties étant les paramètres de la fonction.

Cependant, ce qui est entouré de parenthèses n’est pas toujours une fonction — ce peut être aussi la suite des éléments d’une liste — mais nous le verrons plus tard. Cette notation est de type Préfixe (prefix), car la fonction est devant tout le reste. Si vous êtes habitué à la notation Postfixe (postfix), ou si vous utilisez une calculatrice employant la notation polonaise inverse, (Comme la plupart des calculatrices HP ), vous ne devriez pas avoir de difficulté à vous adapter à la formulation des expressions dans Schème.

La troisième chose à comprendre est que:

Les opérateurs mathématiques sont aussi considérés comme des fonctions, et sont donc mis en premier quand on écrit des expressions mathématiques.

Ceci suit logiquement la notation de type préfixe dont nous venons de parler.


Exemples de notations Préfixe, Infixe, et Postfixe

Voici quelques exemples illustrant la différence entre les notations préfixe, infixe, et postfixe . Il s’agit d’additionner 1 à 3:

Notation Préfixe : + 1 3 (Ce qu’il faut utiliser avec Schème)

Notation Infixe : 1 + 3 (la façon habituelle de l’écrire)

Notation Postfixe : 1 3 + (Utilisée par beaucoup de calculatrices HP)


PRACTICING IN SCHEME

Maintenant, bizut, mettons en pratique ce que nous venons d’apprendre. Lançons Gimp, si ce n’est déjà fait, et choisissons Xtns/Script-Fu/Console. Ceci ouvre la fenêtre Script-Fu Console, qui nous permet de travailler de façon interactive dans Schème. Dans quelques secondes, la console Script-Fu va apparaître.


Figure 43.1 Lancement de la Console Script-Fu

Figure 43.2 La Console Script-Fu


LA FENÊTRE DE LA CONSOLE SCRIPT-FU


On trouve en bas de la fenêtre un champ de saisie nommé Commande en cours (Current Command).

Nous pouvons y tester les commandes simples de Schème de façon interactive. Commençons par quelque chose de simple et additionnons des nombres:

(+ 3 5)

En entrant ceci au clavier et en appuyant sur Entrée (Return) nous attendons comme résultat 8 dans la fenêtre centrale.

Maintenant, comment faire pour ajouter plus d’un nombre? La fonction +” peut s’appliquer à plus de deux arguments, donc pas de problème :

(+ 3 5 6)

Le résultat attendu 14 s’affiche.

Parfait jusque là — nous entrons au clavier une instruction Schème et celle-ci est immédiatement exécutée dans la fenêtre de la Console Script-Fu.

Maintenant, un mot d’avertissement....


SURVEILLEZ LES PARENTHESES SUPPLEMENTAIRES

Si vous êtes comme moi, vous avez l’habitude d’utiliser des parenthèses supplémentaires, par exemple quand vous saisissez une équation mathématique complexe et que vous ajoutez des parenthèses pour en séparer les parties dans le but de faciliter la compréhension par la suite. Avec Schème, vous devrez faire attention à ne pas placer les parenthèses de façon incorrecte.

Par exemple, pour ajouter 3 au résultat de l’addition de 5 et 6:


3 + (5 + 6) + 7= ?


Sachant que l’opérateur + peut additionner une suite de nombres, vous pouvez être tenté de convertir ainsi l’expression ci-dessus :


(+ 3 (5 6) 7)


Cette écriture n’est pas correcte — rappelez-vous, chaque instruction de Schème commence et finit par une parenthèse, et donc l’interpréteur de Schème va croire que vous essayez d’appeler une fonction nommée “5” dans le second groupe de caractères, au lieu d’additionner ces nombres avant de les ajouter à 3.


La bonne façon d’écrire sera:


(+ 3 (+ 5 6) 7)


VERIFIEZ AUSSI QUE VOS ESPACES SONT BONS


Si vous avez l’habitude d’autres langages de programmation, comme C/C++, Perl ou Java, vous savez qu’il n’est pas nécessaire de mettre des espaces entre les opérateurs mathématiques pour bien écrire une expression:


3+5, 3 +5, 3+ 5

Toutes ces formes sont acceptées par les compilateurs C/C++, Perl et Java. Ce n’et pas vrai pour Schème. Il faut mettre un espace après un opérateur mathématique (ou après n’importe quelle fonction nom (name) ou opérateur (operator))dans le cas de Schème pour que l’expression soit correctement interprétée.

Pratiquez un peu avec des équations mathématiques simples dans la Console Script-Fu jusqu'à ce que vous soyez parfaitement à l'aise avec les concepts initiaux.


LEÇON 2: DES VARIABLES ET DES FONCTIONS


Ainsi, mon élève, tu es curieux et veut connaître des choses sur les variables et les fonctions?

Une telle énergie dans ton entraînement — j’aime çà.


VARIABLES

Maintenant que nous avons appris que chaque instruction de Schème est encadrée par des parenthèses, et que la fonction nom/opérateur est placée en tête de la liste, il nous faut apprendre à créer et à utiliser les variables et les fonctions. Nous allons commencer par les variables.


Déclaration des Variables

Bien qu’il existe plusieurs méthodes pour déclarer les variables, la meilleure est la construction let*. Si vous êtes habitué aux autres langages de programmation, cette construction est équivalente à la définition d’une liste de variables locales et le domaine dans lequel elles sont actives. Par exemple pour déclarer deux variables, a et b, initialisées respectivement à 1 et 2 , vous devrez écrire:


(let* (

(a 1)

(b 2)

)

(+ a b)

)



ou, en une seule ligne:


(let* ( (a 1) (b 2) ) (+ a b) )


Note: Vous devez mettre tout sur une seule ligne quand vous utilisez la fenêtre de console.

En général, cependant, vous préférerez adopter une d’indentation analogue pour rendre vos scripts plus lisibles. Nous en parlerons un peu plus dans la section “Espace blanc” page 702.


Ceci déclare les deux variables locales a et b, les initialise, puis imprime la somme des deux variables.


Qu’est-ce qu’une variable locale ?


Vous remarquerez que nous avons écrit l’addition (+a b) à l’intérieur des parenthèses de l’expression let*, et pas après elle.

C’est parce que l’instruction let* définit une zone dans votre script dans laquelle on peut utiliser les variables déclarées; Si vous mettiez l’instruction (+a b) après l’instruction (let*

...), vous obtiendrez une erreur, car les variables déclarées ne sont valides que dans le contexte de l’instruction let*; c’est ce que les programmeurs nomment des variables locales.


La syntaxe générale de let*

La forme générale d’une instruction let* est:


(let* ( variables ) expressions )


dans laquelle les variables sont déclarées à l’intérieur de parenthèses, par exemple (a 2), et où les expressions ne peuvent être que des expressions acceptées par Schème. Rappelez-vous que les variables déclarées ici ne sont valides qu’à l’intérieur de l’instruction let* — ce sont des variables locales.


White Space


Nous avons signalé plus haut le fait que vous voudrez probablement utiliser l’indentation pour organiser vos scripts et les rendre plus clairs. C’est une bonne méthode, et qui ne pose pas de problème avec Schème — Espace blanc est ignoré par l’interpréteur de Schème, et peut donc être largement utilisé.

Cependant, si vous travaillez avec la fenêtre console de Script-Fu’s, il vous faut entrer l’expression entière en une seule ligne; c’est à dire que tout ce qui se trouve entre les parenthèses initiale et finale d’une expression doit être sur une seule ligne dans la fenêtre de console Script-Fu.


Assigner une nouvelle valeur à une Variable


Lorsqu’une variable a été initialisée, vous pouvez avoir besoin de changer ultérieurement sa valeur dans le script. Utilisez l’instruction set! pour changer la valeur d’une variable:


(let* ( (theNum 10) ) (set! theNum (+ theNum \

theNum)) )


Essayez de vous rendre compte de l’effet de cette instruction, puis continuez et entrez dans la fenêtre de la console Script-Fu

Note: “\” indique qu’il n’y a pas de changement de ligne. Ignorez-le (ne le rentrez pas au clavier dans la console Script-Fu et n’appuyez pas sur Entrée), continuez simplement avec la ligne suivante.


FONCTIONS

Maintenant que vous avez saisi le truc pour les variables, travaillons avec des fonctions.

La syntaxe de déclaration d’une fonction est la suivante:

(define ( name param-list) expressions )

(définir ( nom liste des paramètres ) expressions )


nom (name) est le nom assigné à la fonction, liste des paramètres (param-list) une liste de noms de paramètres délimités dans l’espace (space-delimited list of parameter names), et expressions une série d’expressions que la fonction exécute quand elle est appelée. Par exemple:


( define ( AddXY inX inY ) ( + inX inY ) )


AddXY est le nom de la fonction, inX et inY sont les variables. Cette fonction prend deux paramètres et les additionne.

Si vous avez programmé dans d’autres langages impératifs?? (imperatives) (comme C/C++, Java, Pascal, etc.), vous pourrez remarquer l’absence d’un certain nombre de choses dans cette définition de fonction, par rapport à d’autres langages de programmation.


tout d’abord, remarquez que les paramètres n’ont pas de “types” (c’est à dire qu’on ne les déclare pas comme chaînes de caractères (strings), ou entiers (integers), etc.). Schème est un langage sans types (type-less).

C’est pratique et permet d’écrire plus rapidement le script.


Remarquez ensuite que nous n’avons pas à nous préoccuper de la façon de “récupérer” le résultat de la fonction — la dernière instruction (statement) est la valeur « retournée » quand on appelle la fonction. Entrez la fonction dans la console, puis essayez quelque chose comme:

(AddXY (AddXY 5 6) 4)


LEÇON 3: LISTES, LISTES ET ENCORE DES LISTES

Nous vous avons entraîné aux variables et aux fonctions, jeune Script-Fu-ka, et nous allons maintenant vous faire pénétrer dans les marais fuligineux des listes de Schème. Etes-vous prêt à tenter l’aventure ?


DEFINIR UNE LISTE

Avant d’entrer plus avant dans les listes, il faut connaître la difference entre listes (lists) et valeurs atomiques (atomic values).

Vous avez déjà vu des valeurs atomiques quand nous avons initialise des variables dans la leçon précédente. Une valeur atomique est une valeur unique (single value). Nous pouvons par exemple assigner à la variable “x” la valeur unique 8 avec l’instruction suivante:

(let* ( (x 8) ) x)

(Nous avons ajouté l’expression x à la fin pour imprimer la valeur assignée à x—normalement nous n’avons pas à le faire. Notez comment let* agit exactement comme une fonction: La valeur de la dernière instruction est la valeur retournée).

Une variable peut aussi correspondre à une liste de valeurs, au lieu d’une seule. Pour assigner à la variable x la liste de valeurs 1, 3, 5, nous devrons entrer au clavier:

(let* ( (x ’(1 3 5) ) ) x)


Essayez de rentrer ces deux instructions dans la console de Script-Fu et observez le résultat.

Quand vous rentrez la première instruction, le résultat obtenu est simplement :

8

Par contre en rentrant la seconde instruction le résultat est le suivant:

(1 3 5)


En vous retournant la valeur 8 il vous informe que x contient la valeur atomique 8. Par contre en donnant comme résultat (1 3 5), il vous informe que x ne contient pas une valeur unique, mais une liste de valeurs. Notez l’absence de virgules (commas) dans la déclaration d’assignation de la liste, ni dans le résultat imprimé.

La syntaxe de définition d’une liste est:

’( a b c)


où a, b et c sont des littéraux (literals). Nous utilisons l’apostrophe () pour indiquer que ce qui suit entre les parenthèses est une liste de valeurs littérales (list of literal values), et non une fonction ou une expression.

Une liste vide est définie ainsi:

’()

ou plus simplement:

()

Les listes peuvent contenir des valeurs atomiques, ainsi que d’autres listes:



(let*

(

(x ’ ("The Gimp" (1 2 3) ("is" \

("great" () ) ) ) )

)

x

)



Notez qu’après la première apostrophe, vous n’avez pas besoin d’autres apostrophes pour définir les listes intérieures (inner lists). Continuez et écrivez l’instruction dans la console Script-Fu pour voir le résultat.

Vous remarquerez que ce résultat n’est pas une liste de valeurs simples, atomiques mais une liste de littéraux (“The Gimp”), la liste (1 2 3), etc.


COMMENT SE REPRESENTER LES LISTES


Il est utile de se représenter une liste comme composée d’une “tête” et d’une “queue”. La tête étant le premier élément de la liste, la queue le reste. Vous verrez l’importance de cette représentation quand nous regarderons comment ajouter des éléments à une liste et comment accéder à des éléments de la liste


Création de listes par Concaténation

(La fonction Cons)

La fonction Cons est l’une des plus courantes. Elle prend une valeur et la place devant (prepends) son second argument, une liste. Dans le paragraphe précédent, je vous ai suggéré de voir une liste comme composée d’un élément (la tête) et du reste de la liste (la queue). C’est exactement ainsi que fonctionne cons — elle ajoute un élément à la tête de la liste. Vous pouvez donc créer une liste de la façon suivante:


(cons 1 ’(2 3 4) )


Le résultat est la liste (1 2 3 4).


Vous pouvez aussi créer une liste avec un élément:


(cons 1 () )


Vous pouvez utiliser des variables préalablement déclarées au lieu de variables , comme vous pouviez vous y attendre.


Définition d’une liste au moyen de la fonction Liste

Pour définir une liste formée de littéraux ou de variables préalablement déclarées, utilisez la fonction liste:

(list 5 4 3 a b c)

Cette instruction crée et renvoie une liste contenant les valeurs prises par les variables a, b et c. Par exemple:



(let* (

(a 1)

(b 2)

(c 3)

)

(list 5 4 3 a b c)

)



Ce code crée la liste (5 4 3 1 2 3).


ACCEDER AUX VALEURS D’UNE LISTE

Pour accéder aux valeurs d’une liste, utilisez la fonction car qui retourne le premier élément de la liste, et la fonction cdr qui retourne les autres éléments. Ces fonctions décomposent la liste selon le schéma tête::queue vu plus haut.


La fonction car

car retourne le premier élément de la liste (la tête de la liste). Il faut que la liste ne soit pas vide. Ainsi, l’instruction suivante retourne le premier élément de la liste:


(car ’("first" 2 "third"))


qui est:


"first"


La fonction cdr

cdr retourne le tout ce qui suit le premier élément (la queue de la liste). Si la liste ne comprend qu’un élément, cdr retourne une liste vide.


(cdr ’("first" 2 "third"))


retourne:


(2 "third")


alors que:

(cdr ’("one and only"))


retourne:


()


ACCEDER A D’AUTRES ELEMENTS D’UNE LISTE

OK, c’est formidable, nous pouvons avoir le premier élément de la liste, ainsi que le reste de la liste, mais comment accéder au second élément, au troisième ou aux autres? Il existe plusieurs fonctions de “commodités (convenience)” qui le permettent, par exemple, la tête de la tête de la queue de la liste (caadr), la queue de la queue de la liste (cddr), etc.

Le principe de formation du nom de ces fonctions est simple : a et d représentent la tête et la queue de la liste, ainsi


(car (cdr (car x) ) )


peut s’écrire:


(cadar x)


Vous trouverez dans l’annexe C une liste complète de ces fonctions, donnant les fonctions disponibles pour la version de Schème utilisée par Script-Fu.

Pour vous habituer aux fonctions permettant d’accéder à la liste, essayez en rentrant au clavier ce qui suit (mettre tout sur une seule ligne si vous utilisez la console); faites varier car et cdr pour accéder aux différents éléments de la liste:



(let*

(

(x ’ (

(1 2 (3 4 5) 6)

7 8

(9 10)

)

)

)

; place your car/cdr code here

)


Essayez d’accéder au numéro 3 de la liste en n’appelant que deux fois la fonction. Si vous y arrivez, vous êtes sur la bonne voie pour devenir un maître du Script-Fu!


LEÇON 4: VOTRE PREMIER SCRIPT SCRIPT-FU

Veux-tu t’arrêter et reprendre ton soufflé, bizut? Non? Parfait, commençons la quatrième leçon — ton premier script Script-Fu.


CREER UN SCRIPT DE BOITE DE TEXTE (TEXT BOX SCRIPT)


Une des opérations les plus courantes que je fais dans Gimp consiste à créer une boite avec un peu de texte pour mettre dans une page web, un logo ou autre chose. Cependant, on ne sait jamais bien en commençant quelle doit être la taille de l’image initiale. On ne connaît pas la place qu’occupera le texte avec la fonte et la taille choisies pour les caractères.

Le Maître (et l’élève) de Script-Fu réaliseront vite que ce problème peut facilement se régler et s’automatiser avec Script-Fu.

Pour cela nous allons créer un script, nommé boite de texte (Text Box), qui créera une image correctement dimensionnée pour s’ajuster confortablement autour d’une ligne de texte entrée par l’utilisateur. Nous permettrons aussi à l’utilisateur de choisir les caractères (font), la taille des caractères (font size) et la couleur du texte (text color).


COMMENÇONS


Modifier et enregistrer nos scripts


Jusqu’à maintenant nous avons travaillé sur la console Script-Fu. Nous allons maintenant passer sur la modification des fichiers texte de script (editing script text files).

C’est à vous de choisir la place où vous enregistrerez vos scripts — si vous avez accès au répertoire de script par défaut de Gimp, vous pouvez y mettre vos scripts. Toutefois, je préfère conserver mes scripts personnels dans mon propre répertoire de scripts, pour les séparer des scripts installés d’origine.

Dans le répertoire .gimp que Gimp a fait à partir de votre répertoire home , vous pourrez trouver un dossier nommé . Gimp va chercher automatiquement un répertoire de scripts dans votre répertoire .gimp, et ajoutera les scripts dans ce répertoire comme base de données Script-Fu database. Vous pouvez mettre vos scripts à cet emplacement.


L’essentiel

Chaque script Script-Fu définit au moins une fonction, qui est la fonction principale du script. C’est là que vous effectuez le travail.

Chaque script doit aussi s’enregistrer dans la base de données procédures (procedural database), pour vous permettre d’y accéder à l’intérieur de Gimp.

Nous allons commencer par définir la fonction principale:


(define (script-fu-text-box inText inFont inFontSize inTextColor))


Nous venons de définir une fonction nommée script-fu-text-box qui utilise quatre paramètres, paramètres qui correspondront ensuite à du texte, une police de caractères (font), la dimension (size) de la police, et la couleur du texte. La fonction est pour le moment vide et ne fait donc rien.



Conventions de dénomination

Les conventions de dénomination de Schème semblent préférer des lettres ?? (lowercase) avec des traits d’union, ce que j’ai respecté dans la dénomination de la fonction. Je n’ai pas cependant suivi cette convention pour les paramètres. Je préfère des noms descriptifs pour mes paramètres et mes variables, et donc ajouté le préfixe “in” aux paramètres de façon à me permettre de voir rapidement que ce sont des valeurs passées dans le script, plutôt que créées dans celui-ci. J’utilise le préfixe “the” pour les variables définies à l’intérieur du script.

C’est la convention pour Gimp pour dénommer vos fonctions script script-fu-abc, car ensuite quand elles sont listées dans la base de données procédures, elles seront toutes montrées sous script-fu quand vous listerez les fonctions. Ceci aide aussi à les distinguer des greffons (plug-ins).


Enregistrement de la fonction

Enregistrons maintenant la fonction avec Gimp, en appelant la fonction script-fu-register. Quand Gimp lit dans un script, il exécute cette fonction qui enregistre le script avec la base de données procédure. Cet appel de fonction peut se mettre n’importe où dans le script, mais j’ai l’habitude de le mettre à la fin, après toutes mes lignes de codes.

Voici un listing pour enregistrer cette fonction (j’en expliquerai les paramètres dans un instant):

























(script-fu-register


”script-fu-text-box” ;func name


”<Toolbox>/Xtns/Script-Fu/Text/Text Box”;menu pos


”Creates a simple text box, sized to fit around the user’s \

choice of text,font, font size, and color.”


”Michael Terry” ;author


”copyright 1997, Michael Terry” ;copyright notice


”October 27, 1997” ;date created


”” ;Image type that the script works on


SF-VALUE ”Text:” ”\”Text Box\””;a text variable


SF-VALUE ”Font:” ”\”Charter\””;a text variable


SF-VALUE ”Font size:” ”45” ;a text variable

SF-COLOR ”Color:” ’(0 0 0) ;color variable

)



Quand vous enregistrez ces fonctions dans un fichier texte avec un suffixe .scm dans votre répertoire des scripts, choisissez Xtns|Script-Fu|Refresh, ce nouveau script apparaîtra alors comme une boite de texte Xtns|Script Fu|Text|Text Box.


Figure 43.3 Le nouveau script apparaîtra dans le menu après que vous ayez rafraîchi le répertoire Script-Fu


Si vous appelez ce nouveau script, il ne fera bien entendu rien, mais vous pourrez voir les prompts créés à l’enregistrement du script (nous donnerons plus loin plus d’explications sur ce que nous avons fait).


Figure 43.4 La nouvelle boite de dialogue de script


Finalement, si vous appelez le DB Browser (le navigateur de base de données procédure — Xtns|DB Browser), vous pourrez remarquer que votre script apparaît maintenant dans la base de données.



Figure 43.5 le navigateur DB


Les étapes d’enregistrement du script


Pour enregistrer notre script avec Gimp, nous appelons la fonction script-fu-register,

Donnons les valeurs pour les sept paramètres requis et ajoutons les paramètres de notre propre script , avec une description et la valeur par défaut de chaque paramètre.


Les paramètres requis


Le nom (name) de la fonction que nous avons définie. C’est la fonction qui est appelée quand on lance le script (le point d’entrée du script). C’est une nécessité car il nous est possible de définir d’autres fonctions dans le même fichier, et Gimp a besoin de connaître quelle est la fonction à appeler. Dans notre exemple, nous n’avons défini qu’une fonction, text-box, que nous avons enregistrée.

L’emplacement (location) dans le menu dans lequel le script sera inséré. L’emplacement exact du script est spécifié comme un chemin d’accès d’Unix, la racine du chemin étant soit une boite à outils soit un clic-droit.

Si votre script n’agit pas sur une image existante (et donc créée une nouvelle image, comme le fera notre script Text Box), vous allez vouloir insérer celle-ci dans le menu de la boite à outils (toolbox) — c’est le menu de la fenêtre principale de Gimp (dans laquelle se trouvent tous les outils : l’outil de sélection, verre grossissant, etc.).

Si votre script doit agir sur une image à modifier, vous allez vouloir la mettre dans le menu qui apparaît en droitecloquant sur une image ouverte. Le reste du chemin d’accès mène aux listes de menus, aux menus et sous-menus. Par conséquent nous avons enregistré notre script Text Box dans le menu Texte (Text) du menu Script-Fu du menu Xtns de la boite à outils (toolbox) (Xtns|Script-Fu|Text|Text Box).

Vous l’avez peut-être remarqué, le sous-menu Text (Text) du menu Script-Fu n’était pas présent quand nous avons commencé — Gimp crée automatiquement les menus qui n’existent pas déjà.

Une description de votre script. Je ne sais pas avec certitude où elle est affichée.

Votre nom (name) (l’auteur du script).

L’information de Copyright.

La date de création du script, ou de la dernière modification (revision) de celui-ci.

Les types d’images sur lesquelles le script fonctionne. Ce peut être tous les types suivants: RGB, RGBA, GRAY, GRAYA, INDEXED, INDEXEDA, ou aucun d’entre eux —dans notre cas, nous créons une image et n’avons donc pas besoin de définir le type d’image sur lequel nous travaillons.


Enregistrement des paramètres du Script

Une fois listés les paramètres requis, il nous faut lister les paramètres nécessaires à notre script. Quand nous listons ces params, nous fournissons des indications (hints) sur ce que sont leurs types. Ceci pour la boite de dialogue qui surgit quand l’utilisateur sélectionner notre script. Nous fournissons aussi une valeur par défaut.

Cette section du processus d’enregistrement a le format suivant: Param-type ”Prompt text” ”default value”

Les différents types de paramètres, plus des exemples, sont listés dans la Table 43.1.


Table 43.1 Liste des paramètres






Description du type de Param Exemples


SF-VALUE Accepte les nombres et les SF-VALUE “Text:” “\“Some text\””

suites de caractères (strings).

Notez que les guillemets SF-VALUE “A number:” “34”

doivent être supprimés du

texte pour défaut.


SF-COLOR Indique qu’il faut indiquer SF-COLOR “Color:” ’(0 0 0)

une couleur.


SF-TOGGLE Affiche une boite à outils, SF-TOGGLE “Resize?” TRUE

Dans laquelle il faut entrer

Une valeur booléenne


SF-IMAGE Quand votre script agit sur SFIMAGE “The image” 0

une image déjà ouverte,

ce paramètre peut être le

premier après les paramètres

requis. Gimp passera dans

une référence pour l’image dans

ce paramètre.


SF-DRAWABLE Quand votre script agit sur SF-DRAWABLE “The layer” 0

une image déjà ouverte,

ce paramètre peut être le

second après le paramètre

SF-IMAGE. Il concerne le calque

actif. Gimp passera dans

une référence pour le calque actif

dans ce paramètre.





Maintenant, jeune étudiant, tu as eu plein d’informations, fais donc une pause.


LEÇON 5: DONNER DES TRIPES A VOTRE SCRIPT


Tu as montré une grande application dans tes études, mon étudiant. Continuons ton entraînement et ajoutons quelques fonctionnalités à ton script.


CREATION D’UNE IMAGE

Dans la leçon précédente, nous avons créé une fonction vide et l’avons enregistrée avec Gimp.

Dans cette leçon, nous voulons donner une fonctionnalité à notre script —nous voulons créer une image, lui ajouter le texte destiné à l’utilisateur et redimensionner l’image pour qu’elle soit parfaitement adaptée au texte.

Une fois connues les façons de régler les variables, de définir les fonctions et l’accès aux membres de la liste (access list members), le reste coule de source — vous n’aurez besoin que de vous familiariser avec les fonctions disponibles dans la base de données procédures de Gimp, et d’appeler directement ces fonctions. Allumons donc le DB Browser et commençons notre cuisine!

Commençons par la création d’une image. Nous allons créer une variable, theImage, établie comme le résultat du lancement de Gimp’s built-in function gimp-image-new.


Figure 43.6 Le DB Browser


Comme on peut le constater depuis le DB Browser, la fonction gimp-image-new utilise trois paramètres— la largeur (width), la hauteur (height) et le type de l’image. Comme nous redimensionnerons (resize) ultérieurement l’image pour qu’elle s’adapte au texte, nous allons créer une image 10x10 RGB image. Nous allons aussi stocker la largeur et les dimensions de l’image dans quelques variables (in some variables), que nous utiliserons et modifierons ensuite dans le script.


(define (script-fu-text-box inText inFont inFontSize inTextColor)

(let*

(

; define our local variables

; create a new image:

(theImageWidth 10)

(theImageHeight 10)

(theImage (car (gimp-image-new theImageWidth theImageHeight RGB) )

; theText is a declaration for the text we create later

(theText)









Note: Nous avons utilise la valeur RGB pour spécifier que l’image est une image RGB. Nous aurions aussi pu utiliser 0, mais RGB est plus parlant quand nous regardons le code.

Vous avez peut-être remarqué aussi que nous avons pris la tête (head) du résultat de l’appel de la fonction. Ceci peut sembler curieux, car la base de données nous indique explicitement qu’elle retourne une valeur unique —l’ID de l’image nouvellement créée. Cependant, toutes les fonctions Gimp renvoient une liste, même si cette liste ne comprend qu’un seul élément, et nous avons donc besoin de la tête de la liste.


Ajouter un calque à l’image

Nous devons maintenant ajouter un calque à l’image. Nous allons appeler la fonction gimp-layer-new pour créer ce calque, en passant dans l’ID de l’image que nous venons de créer. (A partir de maintenant, au lieu de lister la fonction complète, nous ne listerons que les lignes que nous y ajouterons. Vous pouvez voir le script complet ici). Comme nous avons déclaré toutes les variables locales que nous utiliserons, nous allons aussi fermer les parenthèses marquant la fin de la déclaration des variables:



; create a new layer for the image:

(theLayer (car (gimp-layer-new theImage theImageWidth \

theImageHeight RGB_IMAGE “layer 1” 100 NORMAL) ))

; end of our local variables



Une fois que le nouveau calque est disponible, nous devons l’ajouter à l’image:


(gimp-image-add-layer theImage theLayer 0)


Maintenant, simplement pour le plaisir, regardons le fruit de notre travail et ajoutons cette ligne pour montrer la nouvelle image vide:


(gimp-display-new theImage)


Enregistrons votre travail, sélectionnons Xtns/Script-Fu/Refresh, lançons le script et une image va apparaître. Elle contiendra probablement des déchets (couleurs aléatoires) car nous ne les avons pas effacés. Nous allons nous en occuper dans un instant.


Addition de texte

Avançons et enlevons la ligne d’instructions d’affichage (ou transformons-la en un commentaire avec un ; devant le premier caractère de la ligne).

Avant d’ajouter le texte à l’image, il nous faut choisir les couleurs d’avant et d’arrière plan pour que le texte apparaisse dans la couleur voulue par l’utilisateur. Nous utiliserons pour cela les fonctions gimp-palette-set-back/foreground:


(gimp-palette-set-background ’(255 255 255) )


(gimp-palette-set-foreground inTextColor)


Ceci effectué, nous allons nettoyer l’image de ses déchets. Nous allons sélectionner tout dans l’image, et lancer clear:


(gimp-selection-all theImage)


(gimp-edit-clear theImage theLayer)


(gimp-selection-none theImage)


Nous sommes maintenant prêts à ajouter du texte à l’image nettoyée:



(set! theText (car (gimp-text theImage theLayer 0 0 inText 0 \

TRUE inFontSize PIXELS ”*” inFont ”*” ”*” ”*” ”*”)))



??Although a long function call, it’s fairly straightforward if you go over the parameters while looking at the function’s entry in the DB Browser.??


Basiquement, nous sommes en train de créer un calque de texte et de l’assigner à la variable theText.

Maintenant que nous avons le texte, nous pouvons saisir sa largeur et sa hauteur et redimensionner l’image et le calque de l’image à la taille du texte:



(set! theImageWidth (car (gimp-drawable-width theText) ) )

(set! theImageHeight (car (gimp-drawable-height theText) ) )

(gimp-image-resize theImage theImageWidth theImageHeight 0 0)

(gimp-layer-resize theLayer theImageWidth theImageHeight 0 0)



Si vous êtes comme moi, vous vous demanderez certainement en quoi une ?? (drawable) diffère d’un calque. Cette différence est qu’un ?? (drawable) est quelque chose dans lequel on peut réaliser des traces, un calque est une version particulière des ??(drawable). Dans la plupart des cas, la différence est sans importance.

Notre image étant prête, nous pouvons ajouter de nouveau notre instruction d’affichage:


(gimp-display-new theImage)


Enregistrez votre travail, rafraîchissez la base de données et lancez votre premier script! Vous devriez obtenir quelque chose qui ressemble à la Figure 43.7.


Figure 43.7 Notre boîte de texte



Nettoyage du drapeau sale (Dirty Flag)

Si vous essayez de fermer l’image créée sans l’avoir enregistrée, Gimp vous demandera si vous voulez l’enregistrer avant de la fermer. Il pose cette question car l’image est marquée comme sale (dirty), ou non enregistrée. Dans le cas de notre script, c’est une gêne quand nous voulons seulement effectuer un essai de fonctionnement sans ajouter ou modifier quoi que ce soit de l’image obtenue — notre travail est facilement reproductible avec un script aussi simple, aussi on peut s’affranchir du drapeau sale (irty flag)

Pour ce faire, nous pouvons effacer le drapeau sale après l’affichage de l’image:


(gimp-image-clean-all theImage)


Ceci mettra le compte à 0, la faisant apparaître comme une image “Claire”.

C’est à vous de choisir d’ajouter ou non cette ligne. Je l’utilise dans les scripts pour réaliser des images nouvelles, lorsque les résultats sont triviaux, comme ici. Si votre script est complexe, ou s’il fonctionne sur une image existante, vous préfèrerez probablement ne pas utiliser cette fonction.


LEÇON 6: ETENDRE LE SCRIPT DE LA BOITE DE TEXTE (TEXT BOX SCRIPT)


Votre volonté et votre détermination ne peuvent être arrêtées, mon ardent étudiant. Continuons donc notre apprentissage.


MANIER CORRECTEMENT ANNULER (UNDO)


Quand vous créez un script, vous désirez permettre à vos utilisateurs d’annuler (undo) leurs actions, en cas d’erreur. Ce résultat s’obtient facilement en faisant appel aux fonctions « gimp-undo-push-group-start » et «  gimp-undo-push-group- end » de part et d’autre du code qui manipule l’image. Vous pouvez les considérer comme des instructions associées (matched statements) qui permettent à Gimp de savoir où commencer et finir d’enregistrer les manipulations de l’image, de façon à pouvoir annuler ces manipulations plus tard.

Quand vous créez complètement une image, l’utilisation de ces fonctions n’aurait aucun sens car vous ne modifiez pas une image existante. Par contre si vous modifiez une image existante, vous voudrez sûrement utiliser ces fonctions.

Comme pour cette écriture, l’annulation d’un script fonctionne presque à la perfection en utilisant ces fonctions.

Cependant, il semble qu’il y ait quelques difficultés, et il semble que les difficultés se présentent surtout lorsqu’on lance un autre script n’utilisant pas lui-même ces fonctions.


ETENDRE UN PEU LE SCRIPT

Nous disposons maintenant d’un script très pratique pour créer des boites de texte, ajoutons-lui deux possibilités:

Normalement, l’image est redimensionnée pour s’ajuster exactement au texte — ne laissant aucun espace pour d’autres choses, par exemple des gouttes d’ombre (drop shadows) ou des effets spéciaux (bien que beaucoup de scripts redimensionnent automatiquement l’image si nécessaire). Ajoutons un tampon (buffer) autour du texte, et laissons l’utilisateur choisir la dimension de ce tampon sous la forme d’un pourcentage de la taille du texte.

Ce script pourrait facilement être utilise dans d’autres scripts fonctionnant avec du texte. Etendons-le (extend it) de façon à ce qu’il retourne l’image et le calque, de sorte que d’autres scripts puissent appeler ce script et utiliser l’image et les calques que nous aurons créés.


Modifier les paramètres et la fonction d’enregistrement (Registration Function)


Pour permettre à l’utilisateur de spécifier l’importance du tampon (buffer), nous allons ajouter un paramètre à notre fonction et à la fonction d’enregistrement:



















(define (script-fu-text-box inText inFont inFontSize inTextColor inBufferAmount


(let*


(

; define our local vars



; create a new image:


(theImageWidth 10)


(theImageHeight 10)


(theImage (car (gimp-image-new theImageWidth theImageHeight RGB) ) )


(theText)


(theBuffer)


; create a new layer for the image:


(theLayer (car (gimp-layer-new theImage theImageWidth theImageHeight RGB_IMAGE


“layer 1” 100 NORMAL) ))


)


...


)


(script-fu-register


“script-fu-text-box”


“<Toolbox>/Xtns/Script-Fu/Text/Text Box”


“Creates a simple text box, sized to fit around the user’s choice of text,\


font, font size, and color.”


“Michael Terry”


“copyright 1997, Michael Terry”


“October 27, 1997”


““

SF-VALUE “Text:” “\”Text Box\””


SF-VALUE “Font:” “\”Charter\””


SF-VALUE “Font size:” “45”


SF-COLOR “Color:” ‘(0 0 0)


SF-VALUE “Buffer amount (0 - 100% height of text):” “35”


)




Ajout du nouveau code

Nous allons ajouter ce code à deux endroits: directement avant de redimensionner l’image, et à la fin du script (pour retourner la nouvelle image, le calque et le texte).

Quand nous connaissons la hauteur et la largeur du texte, il nous faut redimensionner ces valeurs sur la base de la quantité de tampon spécifiée par l’utilisateur. Nous ne ferons pas de contrôle d'erreur pour nous assurer que cette quantité est bien dans l'intervalle de 0-100% car ce n'est pas d'une importance vitale, et parce qu'il n'y a aucune raison pour que l'utilisateur ne puisse pas entrer une valeur comme “200” comme pourcentage de tampon à ajouter.



(set! theBuffer (* theImageHeight ( inBufferAmount 100) ) )


(set! theImageHeight (+ theImageHeight theBuffer theBuffer) )


(set! theImageWidth (+ theImageWidth theBuffer theBuffer) )



Nous ne faisons ici que régler le tampon en fonction de la hauteur du texte, et que l'ajouter deux fois à la hauteur et à la largeur de l'image. (Nous l'ajoutons deux fois aux deux dimensions car il faut ajouter le tampon de chaque coté du texte).

Maintenant que nous avons redimensionné l'image pour faire la place à un tampon, il nous faut centrer le texte dans l'image. Ceci est fait en le déplaçant vers les coordonnées (x, y) de (theBuffer , theBuffer). J'ai ajouté cette ligne après avoir redimensionné le calque et l'image:




(gimp-layer-set-offsets theText theBuffer theBuffer)



Enregistrez votre script, et essayez-le après avoir rafraîchi la base de données. Vous devriez obtenir une fenêtre comme celle de la figure 43.8.

Tout ce qui reste à faire est de retourner l'image, le calque et le calque de texte. Après l'affichage de l'image, nous ajoutons la ligne suivante:


(list theImage theLayer theText)


C'est la dernière ligne de la fonction, qui rend cette liste utilisables par d'autres scripts qui voudront l'utiliser.


Figure 43.8 La boite de texte terminée


Pour utiliser notre nouveau script de boite de texte dans un autre script, nous pourrions écrire quelque chose comme:



(set! theResult (script-fu-text-box ”Some text” ”Charter” ”30” ’\


(0 0 0) ”35”) )


(gimp-image-flatten (car theResult))



Félicitations, mon élève, tu es sur le chemin de la ceinture noire de Script-Fu!



Retour au sommaire
Chapitre suivant