Décortiquons un script-fu pour Gimp

19 05 2009

Il n’y a pas de macro enregistrable sous The Gimp comme c’est le cas pour Photoshop. Si vous voulez automatiser des actions répétitives sous The Gimp, il faut passer par l’écriture d’un script-fu.

Plutôt que de relire toujours les mêmes scripts basiques, je vous propose d’analyser un script réel (je m’en sers régulièrement).

Splash screen The Gimp 2.6

Splash screen The Gimp 2.6

Il y a 2 façons de créer des macros ou scripts sous The Gimp :

  • Script-fu : permet d’utiliser un langage dérivé du langage Scheme, celui qui sera présenté dans ce billet, peu lisible et aisé d’accès mais présent sur la majorité des distributions de The Gimp.
  • Python-fu : permet d’utiliser le langage Python pour développer des scripts, plus lisible et aisé d’accès mais présent avant tout sous Linux.

Ces environnements profitent tous les deux du même jeu de procédures.

Le langage Scheme

Si vous êtes habitué à programmer en C, PHP ou tout autre langage procédural et/ou objet, oubliez (presque) tout !

En Scheme, tout est liste.Un appel de fonction ? une liste. Un tableau ? une liste. Une boucle ? une liste…

Et une liste s’écrit entre parenthèses.

Et il va falloir aimer imbriquer les listes, c’est moi qui vous le dit.

Vous êtes prevenus.

Procédures disponibles

The Gimp met à disposition des scripts l’ensemble des fonctions accessibles par l’utilisateurs ainsi que d’autres fonctions.

La liste complète des procédures avec leurs paramètres et un texte d’aide est disponible à travers le Navigateur de procédures. Dans The Gimp 2.6, c’est le menu Aide → Navigateur de procédures.

Navigateur de procédures de The Gimp

Navigateur de procédures de The Gimp

Le script à décortiquer

Le script que je propose de décortiquer fait les actions suivantes :

  • découpage automatique de l’image,
  • réduction de l’image à 500 pixels de large,
  • redimensionnement du canevas (pas l’image) à 510 pixels de large,
  • aplatissement de l’image,
  • ajout d’une bordure noire de 1 pixel de large :
    • sélection de toute l’image,
    • réduction de la sélection de 1 pixel,
    • inversion de la sélection,
    • remplissage de la sélection avec du noir,
    • déselection,
  • passage au mode couleurs indexées (32 couleurs),
  • correction de la première et de la dernière couleur.

Voici le code source du script :

(define (script-fu-frequentation image)
  ; Démarre un niveau de undo
  (gimp-image-undo-group-start image)

  ; Définit les couleurs d'avant-plan (noir) et d'arrière-plan (blanc)
  (gimp-context-set-foreground '(0 0 0))
  (gimp-context-set-background '(255 255 255))

  ; Découpage automatique de l'image
  (plug-in-autocrop 0 image (car (gimp-image-get-active-drawable image)))

  ; Réduit l'image à 500 pixels de large
  (let* ((old-largeur (car (gimp-image-width  image)))
         (old-hauteur (car (gimp-image-height image)))
         (new-largeur 500)
         (new-hauteur (/ (* old-hauteur new-largeur) old-largeur))
        )
    (gimp-image-scale image new-largeur new-hauteur)
  )

  ; Retaille le canevas à 510 pixels de large
  (let* ((old-largeur (car (gimp-image-width  image)))
         (old-hauteur (car (gimp-image-height image)))
         (new-largeur 510)
         (new-hauteur (/ (* old-hauteur new-largeur) old-largeur))
         (new-offsetx (/ (- new-largeur old-largeur) 2))
         (new-offsety (/ (- new-hauteur old-hauteur) 2))
        )
    (gimp-image-resize image new-largeur new-hauteur new-offsetx new-offsety)
  )

  ; Aplatit l'image
  (gimp-image-flatten image)

  ; Sélectionne toute l'image
  (gimp-selection-all image)

  ; Réduit la sélection de 1 pixel
  (gimp-selection-shrink image 1)

  ; Inverse la sélection
  (gimp-selection-invert image)

  ; Remplit la sélection de noir (couleur d'avant-plan)
  (let* ((drawable (car (gimp-image-active-drawable image))))
    (gimp-edit-bucket-fill drawable 0 0 100 0 0 0 0)
  )

  ; Déselectionne tout
  (gimp-selection-none image)

  ; Passe en mode couleurs indexées à 32 couleurs
  ; (gimp-image-convert-indexed image NO-DITHER MAKE-PALETTE 32 FALSE FALSE "")
  (gimp-image-convert-indexed image 0 0 32 0 0 "")

  ; Corrige la première et la dernière couleur
  (let* ((colormap (cadr (gimp-image-get-colormap image))))
    (aset colormap 0 0)
    (aset colormap 1 0)
    (aset colormap 2 0)

    (aset colormap 93 255)
    (aset colormap 94 255)
    (aset colormap 95 255)

    (gimp-image-set-colormap image (* 32 3) colormap)
  )

  ; Termine le niveau de undo
  (gimp-image-undo-group-end image)

)

(script-fu-register "script-fu-frequentation"
		    "<Image>/Script-Fu/AMS/Prépare la fréquentation..."
		    "Prépare la fréquentation DAP"
		    "Frédéric Bisson <zigazou@free.fr>"
		    "Frédéric Bisson"
		    "2008-11-14"
		    "RGB*"
		    SF-IMAGE "Input Image" 0
)

Le script décortiqué

Un script-fu peut contenir plusieurs macros. On parlera ici du cas classique où il n’y a qu’une seule macro définie.

Le script-fu est alors scindé en 2 parties :

  • définition de la macro : contient toutes les actions à réaliser,
  • enregistrement auprès de The Gimp : prévient The Gimp de l’existence de notre fonction et lui indique où elle va devoir se retrouver dans le menu.

Définition

(define (script-fu-frequentation image)
  ...
)

Où :

  • define : indique qu’on va définir une nouvelle fonction,
  • script-fu-frequentation : nom de la fonction qu’il est de bon ton de commencer par script-fu pour que tout le monde puisse s’y retrouver,
  • image : argument de la fonction, elle contiendra l’image en cours,
  • : actions à réaliser quand la fonction est appelée.

Démarrer un niveau undo

(gimp-image-undo-group-start image)

À la manière des rollback en base de données, on va transformer la séquence d’actions en une action unique du point de vue de l’utilisateur.

Sans cette ligne, l’utilisateur devrait faire 13 annulations pour défaire les modifications.

L’image en cours est passée en paramètre.

Définir les couleurs d’avant-plan et d’arrière-plan

Avant/arrière-plan

Avant/arrière-plan

(gimp-context-set-foreground '(0 0 0))
(gimp-context-set-background '(255 255 255))

Ces deux commandes permettent de définir :

  • l’avant-plan à noir (rouge=0, vert=0, bleu=0)
  • l’arrière plan à blanc (rouge=255, vert=255, bleu=255)

Note : L’apostrophe avant la parenthèse indique au langage Scheme de ne pas chercher à exécuter le contenu de la liste (il s’agit ici uniquement de valeurs).

Découpage automatique de l’image

(plug-in-autocrop 0 image (car (gimp-image-get-active-drawable image)))

La commande plug-in-autocrop prend 3 paramètres :

  • 0 : demande au plug-in de fonctionner en mode non-interactif,
  • image : image sur laquelle effectuer l’opération,
  • (car (gimp-image-get-active-drawable image)) : récupère le drawable actif de l’image. La commande gimp-image-get-active-drawable retourne une liste et la commande car permet de récupérer le premier élément de cette liste.

Cette commande est équivalente au menu Image → Découpage automatique de l’image

Menu Image → Découpage automatique de l’image

Découpage automatique de l’image

Notes sur les drawable :

  • un drawable est une zone sur laquelle on peut effectuer des opérations,
  • une image peut contenir plusieurs drawable.
  • un calque et un masque de calque sont des drawable.

Réduction de l’image

(let* ((old-largeur (car (gimp-image-width  image)))
       (old-hauteur (car (gimp-image-height image)))
       (new-largeur 500)
       (new-hauteur (/ (* old-hauteur new-largeur) old-largeur))
      )
  (gimp-image-scale image new-largeur new-hauteur)
)

La commande let* permet de créer des variables locales au bloc :

  • old-largeur : récupère la largeur actuelle de l’image,
  • old-hauteur : récupère la hauteur actuelle de l’image,
  • new-largeur : nouvelle largeur fixée à 500 pixels,
  • new-hauteur : calcule la nouvelle hauteur pour qu’elle soit proportionnelle à la hauteur actuelle, notez l’écriture bizarre du calcul qui revient à faire (old-hauteur×new-largeur)/old-largeur.

Une fois new-largeur et new-hauteur calculées, il suffit d’appeler la commande gimp-image-scale qui correspond à menu Image → Échelle et taille de l’image….

Échelle et taille de l’image

Échelle et taille de l’image

Note : gimp-image-scale prend le mode d’interpolation par défaut (Aucun, Linéaire, Bicubique, Lanczos 3). Il est possible de forcer un mode d’interpolation en utilisant gimp-image-scale-full.

Retaille le canevas à 510 pixels de large

(let* ((old-largeur (car (gimp-image-width  image)))
       (old-hauteur (car (gimp-image-height image)))
       (new-largeur 510)
       (new-hauteur (/ (* old-hauteur new-largeur) old-largeur))
       (new-offsetx (/ (- new-largeur old-largeur) 2))
       (new-offsety (/ (- new-hauteur old-hauteur) 2))
      )
  (gimp-image-resize image new-largeur new-hauteur new-offsetx new-offsety)
)

La commande let* permet de créer des variables locales au bloc :

  • old-largeur, old-hauteur, new-largeur, new-hauteur : le principe est le même que pour l’explication précédente,
  • new-offsetx, new-offsety : décalage de l’image actuelle dans le nouveau canevas, valeurs calculées pour placer l’image au centre.

La commande gimp-image-resize correspond au menu Image → Taille du canevas…

Taille du canevas

Taille du canevas

Aplatit l’image

(gimp-image-flatten image)

La commande gimp-image-flatten correspond au menu Image → Aplatir l’image.

Menu Image → Aplatir l’image

Menu Image → Aplatir l’image

Sélectionne toute l’image

(gimp-selection-all image)

La commande gimp-selection-all correspond au menu Sélection → Tout.

Menu Sélection → Tout

Menu Sélection → Tout

Réduit la sélection de 1 pixel

(gimp-selection-shrink image 1)

La commande gimp-selection-shrink correspond au menu Sélection → Réduire…

Réduire la sélection

Réduire la sélection

Inverse la sélection

(gimp-selection-invert image)

La commande gimp-selection-invert correspond au menu Sélection → Inverser.

Menu Sélection → Inverser

Menu Sélection → Inverser

Remplit la sélection de noir

Outil pot de peinture

Outil pot de peinture

(let* ((drawable (car (gimp-image-active-drawable image))))
 (gimp-edit-bucket-fill drawable 0 0 100 0 0 0 0)
)

La commande gimp-edit-bucket-fill correspond à l’outil pot de peinture. Elle travaille sur un drawable et non sur l’image.

Cette commande prend 8 paramètres :

  • drawable : le calque sur lequel effectuer le remplissage,
  • 0 : type de remplissage, 0=couleur de premier plan,
  • 0 : mode de remplissage, 0=mode normal,
  • 100 : opacité en pourcentage,
  • 0 : seuil de sensibilité,
  • 0 : utiliser l’option Remplir via Composite, 0=non,
  • 0 0 : coordonnée x et y où effectuer le remplissage.

Désélectionne tout

(gimp-selection-none image)

La commande gimp-selection-none correspond au menu Selection → Aucune.

Menu Sélection → Aucune

Menu Sélection → Aucune

Mode couleurs indexées

(gimp-image-convert-indexed image 0 0 32 0 0 "")

Les paramètres utilisées sont :

  • image : l’image à convertir,
  • 0 : tramage des couleurs, 0=pas de tramage,
  • 0 : type de palette, 0=générer une palette optimale,
  • 32 : nombre de couleurs,
  • 0 : active le tramage de la transparence, 0=non,
  • 0 : enlever les couleurs non utilisées de la palette, 0=non,
  • «  » : nom de la palette, inutilisé pour une palette optimale.

La commande gimp-image-convert-indexed correspond au menu Image → Mode → Couleurs indexées…

Mode couleurs indexées

Mode couleurs indexées

Corrige les couleurs

(let* ((colormap (cadr (gimp-image-get-colormap image))))
  (aset colormap 0 0)
  (aset colormap 1 0)
  (aset colormap 2 0)

  (aset colormap 93 255)
  (aset colormap 94 255)
  (aset colormap 95 255)

  (gimp-image-set-colormap image (* 32 3) colormap)
)

La commande let* permet de créer une variable locale au bloc. La variable colormap reçoit ainsi la palette de couleurs utilisées par l’image courante sous forme de liste.

La liste contient 1 valeur par composante (rouge, vert, bleu). La palette ayant été précisée à l’étape précédente à 32 couleurs, on a donc une liste de 96 valeurs :

  • les valeurs d’index 0, 1, 2 correspondent aux composantes de la première couleur,
  • les valeurs d’index 93, 94, 95 correspond aux composantes de la dernière couleur.

La commande aset permet de positionner une valeur dans la liste. Il faut donc 3 appels à cette commande pour modifier une couleur de la palette.

Finalement, la commande gimp-image-set-colormap permet de réaffecter la palette de couleurs ainsi créée à l’image. Ses paramètres sont :

  • image : l’image à modifier,
  • (* 32 3) : nombre d’entrées dans la liste (32 couleurs×3 composantes),
  • colormap : la nouvelle palette.

La commande gimp-image-set-colormap est équivalente à l’action de modifier la palette :

Réglage de la palette

Réglage de la palette

Termine le niveau undo

(gimp-image-undo-group-end image)

La commande gimp-image-undo-group-end permet de terminer le bloc undo débuté au tout début de la fonction.

Enregistre la macro auprès de The Gimp

(script-fu-register "script-fu-frequentation"
                    "<Image>/Script-Fu/AMS/Prépare la fréquentation..."
                    "Prépare la fréquentation DAP"
                    "Frédéric Bisson <zigazou@rouen.fr>"
                    "Frédéric Bisson"
                    "2008-11-14"
                    "RGB*"
                    SF-IMAGE "Input Image" 0
)

La commande script-fu-register permet de prévenir The Gimp de l’existence de notre fonction avec les paramètres suivants :

  • « script-fu-frequentation » : la fonction à enregistrer s’appelle script-fu-frequentation,
  • « <Image>/Script-Fu/AMS/Prépare la fréquentation… » : la fonction sera accessible depuis le menu Script-Fu → AMS → Prépare la fréquentation,
  • « Prépare la fréquentation DAP » : description de la fonction,
  • « Frédéric Bisson <zigazou@rouen.fr> » : auteur
  • « Frédéric Bisson » : copyright,
  • « 2008-11-14 » : date de création/modification,
  • « RGB* » : modes de couleurs supportés (RGB*=RGB+RGBA),
  • SF-IMAGE « Input Image » 0 : premier et seul paramètre de la fonction.

Note

D’autres techniques et astuces dans le développement de scripts Gimp sont abordées dans le billet Retoucher les zones sombres/lumineuses (script Gimp).


Actions

Information

39 responses

19 05 2009
Daily News About Linux : A few links about Linux - Tuesday, 19 May 2009 14:39

[…] Décortiquons un script-fu pour Gimp […]

31 08 2009
Bean

Bonjour,
j’ai lu votre article avec beaucoup d’intérêt.
Je suis en train de créer un script fu pour régler le niveau d’une image.
ça se passe les étapes suivantes:
je copie l’image dans gimp
crée un nouveau calque avec opacité 40 et couleur grise, et nommé « calque »
fusionne les deux calque
modifier le niveau.
J’ai déjà fais une partie du code, mais quand je teste, il y a un message d’erreur : « Error: eval: unbound variable: calque

Pourriez vous m’aider pour réaliser ce script?
Merci d’avance

Voici le code:
(define (script-fu-niveaux-bean image)

;demarrer undo
(gimp-image-undo-group-start image)

;Nouveau calque
(gimp-layer-new image 1000 1000 RGBA-IMAGE « calque » 100 NORMAL)
(gimp-image-add-layer image calque -1)

;definir la couleur grise
(gimp-context-set-foreground ‘(233 233 233))

;Remplissage
(gimp-edit-bucket-fill « calque » 0 0 40 0 0 0 0)

;Termine le niveau de undo
(gimp-image-undo-group-end image)
)

(script-fu-register « script-fu-niveaux-bean
« /Script-Fu/AMS/Niveaux bean… »
« Traitement »
«  »
« Bean »
« 2009-08-31 »
« RGB* »
SF-IMAGE « Input Image » 0

)

31 08 2009
zigazou

Bonjour,

Le problème vient de ces 2 lignes :
(gimp-layer-new image 1000 1000 RGBA-IMAGE “calque” 100 NORMAL)
(gimp-image-add-layer image calque -1)

Tout d’abord, il ne faut pas confondre « calque » et calque : le premier est une chaîne de caractère tandis que le second est un nom de variable.

Ensuite, la deuxième ligne tente d’utiliser la variable calque qui n’a été définie nulle part ailleurs.

Il faudrait procéder comme suit :
(let* ((calque (gimp-layer-new image 1000 1000 RGBA-IMAGE “calque” 100 NORMAL)))
(gimp-image-add-layer image calque -1)
)

(code non testé mais ça devrait être grosso-modo la source du problème)

1 09 2009
Bean

Effectivement il s’agit de la déclaration de variable, merci beaucoup.
Par contre maintenant c’est la fonction de remplissage qui pose problème: j’aimerais remplir le nouveau calque d’une couleur grise d’opacité 40. Mais:
soit je mets : (gimp-edit-bucket-fill calque 0 0 40 0 0 0 0)) ça ne marche pas à cause de la déclaration de variable probablement,
soit en utilisant votre code (let* ((drawable (car (gimp-image-active-drawable image))))
(gimp-edit-bucket-fill drawable 0 0 40 0 0 0 0)
))
ça ne marche pas non plus,
pour plus de précision je vous recopie le code entier:
(define (script-fu-niveaux-bean image calque)

;demarrer undo
(gimp-image-undo-group-start image)

;Nouveau calque
(let* (
(largeur (car (gimp-image-width image)))
(hauteur (car (gimp-image-height image)))
(calque 0)
)

(set! calque(car (gimp-layer-new image
largeur
hauteur
RGBA-IMAGE
« calque »
100
NORMAL)))
(gimp-image-add-layer image calque -1)

;definir la couleur grise
(gimp-context-set-foreground ‘(233 233 233))

;Remplissage
;(gimp-edit-bucket-fill calque 0 0 40 0 0 0 0))
(let* ((drawable (car (gimp-image-active-drawable image))))
(gimp-edit-bucket-fill drawable 0 0 40 0 0 0 0)
))

;Termine le niveau de undo
(gimp-image-undo-group-end image)
)

(script-fu-register « script-fu-niveaux-bean »
« /Script-Fu/AMS/Niveaux-bean… »
« Traitement »
«  »
« Bean »
« 2009-08-31 »
« RGB* »
SF-IMAGE « Input Image » 0
SF-DRAWABLE « calque » 0)

1 09 2009
Bean

finalement ça marche, j’ai utilisé la procédure gimp-edit-fill au lieu de gimp-edit-bucket-fill

du coup j’ai pu aussi faire la fusion des calques et le niveaux, j’ai juste à faire en sorte que tout ceci se fait par lot

Merci

1 09 2009
zigazou

Cool, content pour toi !

@+

1 12 2009
papyRox

Bonjour,

C’est hyper bien vos explications. Bravo!!!

Serait-il possible de réaliser un script contenant plusieurs procédures comme par exemple:

Ayant activé le script, au moment d’un clic gauche sur l’image,
1 – capture de la couleur pointée avec la pipette;
2 – sélection de la zone choisie par la baguette magic;
3 – copie de cette sélection;
4 – passer de l’image à un calque transparent prédéterminé;
5 – coller la sélection sur le calque;
6 – remplir la sélection par la couleur capturée en 1;
7 – demander confirmation avant ancrage;
8 – si pas ancrage, annulation des procédures;
9 – Dans tous les cas, retour à l’image de base avec le script activé…

A votre avis, est-ce réalisable ?

Par ailleurs, où pourrais-je trouver les correspondances pour toutes les fonctions de Gimp ? Dans le style que vous utilisez ci-dessus, c’est simplement magnifique.

Bien à vous,
PapyRox

2 12 2009
zigazou

Pour avoir la liste de toutes les fonctions accessibles depuis Script-Fu ou Python-Fu sous The Gimp 2.6, allez dans Filtres → Script-Fu → Console.

Une fenêtre console apparaît alors. En cliquant sur le bouton Parcourir…, le navigateur de procédures apparaît avec toutes les informations nécessaires (paramètres, types de paramètres, valeurs de retour, description de la fonction etc.).

Il y a une convention de nommage : toutes les fonctions standard de Gimp commencent par gimp-, les greffons par plug-in-, les scripts Script-Fu par script-fu- etc. (oui, vous pouvez appeler vos propres scripts à partir d’autres scripts).

Pour votre script, les fonctions suivantes devraient vous aider :
1 − gimp-image-pick-color
2 − gimp-fuzzy-select ou gimp-fuzzy-select-full
3 − gimp-edit-copy ou gimp-edit-named-copy
4 − gimp-image-add-layer
5 − gimp-edit-paste ou gimp-edit-named-paste
6 − gimp-edit-fill
7,8,9 − je n’ai jamais créé de fenêtre dans mes scripts Gimp, mais si votre script s’arrête avant l’étape 7, il ne vous reste plus qu’à cliquer sur le bouton ancrage dans les fenêtres standard de Gimp ou à faire un Control+Z, à condition d’avoir inclus votre code dans un groupe undo (gimp-image-undo-group-start/end).

2 12 2009
papyRox

Bonjour Zigazou,
Un tout grand merci pour une réponse aussi rapide.
Dès que je peux, je m’y colle et je ne manquerai pas de vous tenir au courant de l’évolution de mon premier script.

Bien à vous,
PapyRox

20 12 2009
Retoucher les zones sombres/lumineuses (script Gimp) « Le blog de Zigazou

[…] J’avais déjà fait un billet “Décortiquons un script-fu pour Gimp”. […]

8 01 2010
Gaëtan

Génial ce post ! Clair, précis, instructif …

Merci

2 03 2010
Shadow

Bonjour,

Avant tout merci pour ce script, depuis quelque temps je voulais me lancer dans la programmation de script-fu et le langage me rebutait, la je crois que je vais me lancer finalement.
Je fais des photos sur que je mets en ligne sur mon site : http://www.ombre-x-lumiere.fr
Je voudrais de manière automatique mettre un cadre et mon logo qui est en fait un autre calque et ce avec un traitement par Lot.

— Ouvrir une 1 photo
— faire appel au script Filtre –> décors –> calque
— spécifier les valeurs de couleurs
— Faire mon cadre
— Ouvrir une nouvelle photo (Mon logo)
— Le positionner en bas a droite (position relative)
— Aplanir l’image
— Enregistrer sous…
— passer à l’image suivante

Il y a quelques soucis que je visualise si qq a des pistes…
— Comment faire appel à un autre script (Décors) et surtout comment passer les paramètres de cet autre script en argument du mien
— Comment positionner ma nouvelle image
— La gestion du traitement par lot

Merci de pistes qui pourraient m’aider à commencer.
Cdlt

20 04 2010
zigazou

« Comment faire appel à un autre script (Décors) »
il suffit de l’appeler par son nom ! 😉 Je pense que tu pourras le trouver en parcourant la PDB et en recherchant les scripts dont le nom commence par « script-fu-« . Les scripts peuvent être lancés en mode non-interactif, il suffit de le préciser lors de l’appel à la fonction.

« comment passer les paramètres de cet autre script en argument du mien »
Je ne comprends pas ce que tu veux faire. Ne voulais-tu pas dire « passer les paramètres de mon script en paramètres de cet autre script » ?

« Comment positionner ma nouvelle image »
le principe va être d’ouvrir ton logo, de copier son premier calque, de le coller dans ton image et de le positionner avec la fonction gimp-set-layer-offsets.

« La gestion du traitement par lot »
Si tu regardes dans les commentaires suivants, tu devrais avoir une réponse à ta question.

19 04 2010
hibikiokay

bonsoir

je viens de trouver ton script et il correspond (presque exactement a ce que je veux faire (j’ai plus de 800 images a traiter)

ce que j’aimeras savoir c’est comment faire pour utiliser ton script car quand je tente de le faire dans gimp j’ai presque a chaque ligne de messages d’erreurs

je t’en remerci

19 04 2010
hibikitokay

j’explique plus en detail ce que je voudrais faire (traiter toutes les images qui ce trouvent dans un dossier)

1° ouvrir une des images
2° redimentionner l’image a 550 de haut (largeur variable en fonction du ratiau)
3° inserer un canevas de 450 de largeur
4° centrer l’image dans le canevas
5° créer un cadre de 1px autour de l’image (canevas compris)
6° sauvegarder l’image et passer a la suivante

je te remerci pour toutes l’aides que tu m’aporteras

(j’ai passer pas mal de temps a realiser un script a partir du tiens mais je n’y arrive pas)

merci

20 04 2010
zigazou

Initialement TinyScheme ne dispose pas de fonctions de manipulation de système de fichiers. Les développeurs de Gimp ont toutefois, dans leur grande bonté, inclus une bibliothèque qui répond au doux nom de TSX et qui comble ces lacunes.

Mais comme les choses ne sont pas toujours simples, ils ont renommé certaines fonctions et elles ne sont pas visible en passant par la PDB…

Ton script devrait ressembler plus ou moins à ça :

; Définition de la fonction de traitement d’un fichier
(define (traitement fichier)
; traitement d’un fichier avec file-jpeg-load et file-jpeg-save
)

; On parcourt le répertoire
(let* ((repertoire (dir-open-stream « TONREPERTOIRE »))
(fichier «  »)
)

; Boucle de traitement
(while (not (eof-object? (set! fichier (dir-read-entry repertoire))))
(traitement fichier)
)
)

Pour pouvoir mieux répondre à ta question, pourrais-tu préciser les messages d’erreur que tu obtiens ? Car il n’y a que du très basique dans le script et une erreur à chaque ligne me paraît bizarre.

Question subsidiaire : serais-tu fan de Vandread ???

20 04 2010
hibikitokay

merci

pour ta question final oui, oui et encore oui (entre autre bien sur) (ps: chaqu’une des images est prevut pour illustrer une des series d’animes que j’ai.

pour les messages
> (gimp-image-undo-group-start image)
Error: eval: unbound variable: image
> (gimp-context-set-foreground ‘(0 0 0))
(#t)
> (new-largeur 500)
Error: eval: unbound variable: new-largeur
> (new-largeur 510)
Error: eval: unbound variable: new-largeur
> (gimp-image-flatten image)
Error: eval: unbound variable: image

je pense que les erreures viennent de mois mais comme je ne comprend pas…

chaqu’une des images porte le nom de « animes_*** » les *** corespondent au numeros d’enregistrement dans ma base de donnée MySQL.
je suis peut etre un peut bete mais j’ai du mal a comprendre ta reponse, c’est en complement de ton script ou a la place?

merci

21 04 2010
zigazou

Hello !

“> (gimp-image-undo-group-start image)”
Si tu cherches à exécuter les lignes une par une dans la console, c’est normal que ça ne marche pas. Le message d’erreur t’indique juste que la variable image n’a jamais été définie.

Pour tester ton script, il faut l’enregistrer dans un fichier .scm et le placer dans le répertoire de scripts de Gimp. Sous Linux, c’est généralement le répertoire .gimp-2.6/scripts dans le répertoire de l’utilisateur. Si Gimp est en train de tourner, il faut lui indiquer qu’il y a eu des modifs en allant dans Filtres → Script-Fu → Actualiser les scripts.

Comme je n’ai pas été très clair ou été un peu rapide sur le traitement par lot, tu peux jeter un œil au billet https://zigazou.wordpress.com/2010/04/21/traitement-par-lot-sous-gimp-2-6/

21 04 2010
Traitement par lot sous Gimp 2.6 « Le blog de Zigazou

[…] par lot sous Gimp 2.6 21 04 2010 J’ai déjà décortiqué un script pour The Gimp. Il s’agit d’un script tout ce qu’il y a de plus classique : un script qui travaille sur une […]

24 04 2010
bily2kid

Bonjour Zigazou,
Un tout grand merci pour ces explications precises.
Neanmoins je rame pour inclure une etape de cisaillement dans mon script.

voila ou je galere:

; cisaille l image de 10 px verticalement
(let* ((drawable (car (gimp-shear image))))
(gimp-shear drawable 1 10 0 true 3 0)
)

je n arrive pas a comprendre comment par

24 04 2010
bily2kid

la suite:
je n arrive pas a comprendre comment parametrer l action

j ai une image de 250 x 250 pixels

je veux la cisailler (l’incliner) verticalement de 10 pixels, autrement dit obtenir un losange de 250 px de large par 260 px de haut dont les cotés haut et bas sont inclines de 10 px,

avec un lien ce sera plus clair

merci

25 04 2010
zigazou

Hello !

la ligne
(let* ((drawable (car (gimp-shear-image))))
ne devrait-elle pas plutôt être quelque chose comme :
(let* ((drawable (car (gimp-image-get-active-drawable image))))

25 04 2010
bily2kid

Hello Zigazou,

Merci pour ta reponse si rapide.
j’ ai donc changé la ligne pour:

; cisaille l image de 10 px verticalement
(let* ((drawable (car (gimp-image-get-active-drawable image))))
(gimp-shear drawable 1 10 0 true 3 0)
)
et j obtiens un nouveau message d’erreur de Gimp a propos du script,
(qui semble avoir lieu a la ligne suivante du script, cette fois):

Erreur d’exécution « script-fu-cisaille » :
Error: eval: unbound variable: true

Il me semble que c est un probleme de parametres, non ? mais je ne comprends pas comment renseigner cette partie du script, le navigateur de procedure donne bien des parametres pour « gimp-drawable-transform-shear » mais manifestement je n ai pas bien compris…

merci pour ton aide

25 04 2010
zigazou

Le message “Error: eval: unbound variable: true” signifie simplement que l’interpréteur de script ne connaît pas la variable true.

Ton erreur vient du fait que l’interpréteur est sensible à la casse : “true” est différent de “TRUE”. Or c’est TRUE en majuscule qu’il faut utiliser.

25 04 2010
bily2kid

YES !
Ca marche nickel, je vais gagner un temps fou !
Voici donc le script exact pour automatiser l’outil cisaillement:

; cisaille l image de 10 px verticalement
(let* ((drawable (car (gimp-image-get-active-drawable image))))
(gimp-drawable-transform-shear-default drawable ORIENTATION-VERTICAL 10 TRUE TRANSFORM-RESIZE-ADJUST)
)

Voici les 4 parametres a renseigner (sensible à la casse et séparés par un espace) :

-Type de cisaillement: ORIENTATION-HORIZONTAL, ORIENTATION-VERTICAL
-Amplitude du cisaillement en pixels (ici: 10)
-Utiliser interpolation ou supersampling (pour réechantilloner): TRUE ou FALSE
-Comment sera découpé le resultat: TRANSFORM-RESIZE-ADJUST, TRANSFORM-RESIZE-CLIP, TRANSFORM-RESIZE-CROP, TRANSFORM-RESIZE-CROP-WITH-ASPECT

Un grand merci a toi pour tes explications limpides, et ton attention.

27 04 2010
hibikitokay

un grand merci a toi j’ai put faire toutes les images en quelques secondes
plusieurs heures de gagné grace a ton aide

le prochain je tenterais de le faire par moi même

a plus

saurait tu si il existe un endroit ou trouver des script tous fait, pour ne pas refaire quelque chose qui existe deja

merci encore

27 04 2010
zigazou

Tu peux déjà commencer par là, c’est un bon départ :
http://registry.gimp.org/

23 07 2010
toudou

Tres interressant ce post, merci!

J’ai cherche des infos sur les script-fu, mais apparement beaucoup de docs ne sont pas a jour!

Serait t’il possible que tu postes un simple script qui cree un calque vide? J’ai reussi a faire quelques .scm, mais la creation de calque reste pour moi encore assez obsure.

J’ai une autre question 🙂

J’ai fait un script, qui rajoute des bordures, change la luminosite et quelques effets, aucune erreur sur le script, mais bizarrement les changements n’apparaissent que lorsque je clique sur le dernier evenements dans l’onglet ‘historique’, aurais-tu deja rencontre cette bizarerie?

merci et bonne journee!

David.

23 07 2010
zigazou

Pour créer un calque, cela se passe en 2 temps :

  • – création du calque
  • – attachement du calque à l’image

C’est la même chose pour les masques de calque.

En code, cela donne :
; Création d’un nouveau calque
(let* ((base (car (gimp-layer-new-from-drawable drawable image))))
; Ajoute le nouveau calque à l’image
(gimp-image-add-layer image base -1)

; Traitements sur le calque

)

(j’en parle un peu plus dans ce billet https://zigazou.wordpress.com/2009/12/20/retoucher-les-zones-sombreslumineuses-script-gimp/ )

Pour ton problème de rafraîchissement tu as peut-être besoin d’ajouter un appel à (gimp-displays-flush) après tes traitements.

23 07 2010
toudou

Merci je vais lire le post en question 🙂 Et c’etait bien le rafraichissement qui manquais! Super!

23 07 2010
toudou

Je ne voudrais pas abuser de ton temps, mais ca me rendrait bien service, si tu pouvais voir mon problem :s

J’obtiens 2 erreurs en essayant de creer un calque (le script marche bien sinon):

* GIMP Avertissement
Plug-In ‘Contours’ left image undo in inconsistent state, closing open undo groups.

* GIMP Erreur
Erreur d’exécution « Contours » :
Error: eval: unbound variable: base

######################################
Code
######################################

(define (contours_pic image drawable)

(gimp-image-undo-group-start image)

; Création d’un nouveau calque
(let* ((base (car (gimp-layer-new-from-drawable drawable image)))))

; Ajoute le nouveau calque à l’image
(gimp-image-add-layer image base -1)

(gimp-selection-all image)

(gimp-selection-shrink image 3)

(gimp-selection-invert image)

(gimp-context-set-default-colors)

(gimp-edit-fill drawable FOREGROUND-FILL)

(gimp-selection-none image)

(plug-in-blur RUN-NONINTERACTIVE image drawable)

(gimp-layer-set-opacity drawable 50)

(gimp-displays-flush)

(gimp-image-undo-group-end image)

)

######################################
(je n’ai pas inclu la partie « register »)

23 07 2010
zigazou

Tu as une parenthèse fermante de trop à cette ligne :
(let* ((base (car (gimp-layer-new-from-drawable drawable image)))))

Il devrait y en avoir 4 et non 5…

let* se construit de la manière suivante :
(let* (définition des variables locales)
traitement
traitement

)

Les traitements font partie intégrante de let* et peuvent donc utiliser les variables définies par let*.

Note : tu crées un calque mais tu ne sembles pas l’utiliser.

25 08 2010
Tibo

Salut !

Je veux faire exactement pareil que dans ton exemple avec la reduction du nombre de couleur (postérisation?) et le changement d’une couleur mais je voudrai choisir automatiquement la couleur la plus claire pour la remplacer par du blanc (scanner des feuilles rend le fond gris), mais je n’y arrive pas…

avant de lire ton post j’avait pensé à :
file-jpeg-load ou file-bmp-load ; pour charger l’image
gimp-posterise ; pour réduire le nombre de couleurs
gimp-palette-get-info ; pour être sur du nombre de couleurs
gimp-palette-is-editable ; pour être sûr que l’on peut changer les couleurs
gimp-palette-entry-get-color ; pour lire les couleurs et voir la plus claire
//puis script dans un langage, lequel ? pour sélectionner la couleur la plus claire.
gimp-palette-entry-set-color ; pour mettre du blanc (#ffffff) à la place
file-png-save-defaults ; pour enregistrer l’image en PNG

Mais j’ai vu que tu utilise « convert-indexed » (est-ce la même chose que « posterize » ?) et « colormap » (est-ce pour ne pas à avoir à sélectionner la palette ?)

Bref comment faire pour sélectionner automatiquement la couleur la plus claire ? ou au moins connaître sa position dans la colormap ou la palette ?

Salut et merci d’avance pour la réponse.

P.S. c’est pour faire du traitement par lots (batch) avec des textes sortis de mon scanner avec un fond gris, donc remplacer le gris de toutes les images (évidement pas le même gris partout, ce serai trop beau!) par du blanc.

25 08 2010
zigazou

Salut !

Dès l’instant où tu disposes de la palette en TinyScheme, ce langage est largement suffisant pour rechercher la couleur la plus claire.

Maintenant, la question existentielle : qu’entends-tu par “couleur la plus claire” ? C’est une question qui peut paraître saugrenue au premier abord. Mais, pour toi, la couleur la plus claire, est-ce la couleur dont la moyenne (R+V+B)/3 est la plus grande ? dont la valeur en mode TSV est la plus grande ? dont la luminosité en mode TSL est la plus grande ? Dont la luminosité en mode LAB est la plus grande ? etc.

Une fois cette question résolue, il ne reste plus qu’à écrire une fonction max-clarete qui va rechercher la couleur la plus claire dans la palette.

Quelque chose qui ressemblerait à :
(define (max-clarete couleur palette)
(cond
((null? palette) couleur)
((< (clarete couleur) (clarete (car palette))) (max-clarete (car palette) (cdr palette))
(else (max-clarete couleur (cdr palette)))
)
)

Le code a été écrit tout de go et n’a pas été testé. Mais le principe de base est là !

J’essaierai de regarder plus en avant quand tu auras définie la “clareté”.

Concernant convert-indexed et posterize, ce sont deux fonctions complètement différentes même si au final elles réduisent le nombre de couleurs d’une image. L’utilisation de l’une ou l’autre dépend de ce que tu recherches comme effet. De plus, une image RVB postérisé reste RVB alors qu’avec convert-indexed, une image RVB devient une image INDEXED.

Concernant ton utilisation de gimp-palette-*, il me semble que tu fais fausse route. Les fonctions gimp-palette-* permettent de manipuler des palettes de couleur mais ces palettes ne sont pas associées à des images. Il y a une petite confusion dans la traduction française de Gimp : colormap et palette sont tous les deux traduits par palette. Attention : les colormap ne sont disponibles qu’avec des images INDEXED (colormap va donc souvent de pair avec convert-indexed).

25 08 2010
Tibo

Ok, merci beaucoup ! J’aurai cherché des heures avec ma palette ! Mais je me doutais que ça ne fonctionnait qu’avec de l’indexé : pour l’instant je le fais manuellement et c’est le cas.

quant à la clareté, à mon avis, n’importe laquelle fonctionne car je réduit mon image vers 9 à 17 couleurs maxi et c’est du texte : en général ma map (palette) est très noire avec un seul carré clair.

J’essaie de te donner une réponse ce WE : j’ai des rattrapages en ce moment…

à+ et merci encore !

1 09 2010
Tibo

Bon, j’ai essayé… mais ça ne fonctionne pas : plus j’essaye d’enlever des erreurs et plus il y en a, peut-tu m’aider à déméler les principales erreurs afin que je termine le débuggage ?

Voici le code :

(define (script-fu-scannerblanc pattern)

(let* ((filelist (cadr (file-glob pattern 1))))
(while (not (null? filelist))
(let* ((filename (car filelist))
(image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
; chargement de l’image
; Passe en mode couleurs indexées à 32 couleurs à activer si besoin
; (gimp-image-convert-indexed image NO-DITHER MAKE-PALETTE 32 FALSE FALSE «  »)
; (gimp-image-convert-indexed image 0 0 32 0 0 «  »)

; Corrige la couleur
(let* ((colormap (cadr (gimp-image-get-colormap image))))
(max-clarete ;trouve la position du maximum de clarete
(aset colormap posclair 255) ; met la valeur max au rouge de la couleur claire
(aset colormap posclair+1 255) ; met la valeur max au vert de la couleur claire
(aset colormap posclair+2 255) ; met la valeur max au bleu de la couleur claire

(gimp-image-set-colormap image (* * 3) colormap) ; on sauvegarde la palette
)
(gimp-file-save RUN-NONINTERACTIVE image drawable filename filename) ;on sauve
(gimp-image-delete image))
(set! filelist (cdr filelist)))))

)

(define (max-clarete colormap) ; on créé la fonction pour trouver la couleur la plus claire
(cond
((null? colormap) couleur1 couleur2 couleur3); on prend les 3 couleurs RGB
((< (couleur1) (clarete (car colormap))) (posclair (car colormap) (cdr colormap)); on prend la case avec le plus de rouge
(else (posclair couleur (cdr colormap)))
(posclair=abs(posclair/3) ; on positionne posclair sur la première couleur RGB
)
)

(script-fu-register "script-fu-scannerblanc"
"/Script-Fu/Photos/Scanner_gris_au_blanc »
« Transforme la couleur de fond grise d’une page scannée au blanc »
« Multi »
« Multi »
« 2010-09-01 »
« RGB* »
)

Merci 🙂

1 09 2010
zigazou

Hello !

Tu pourras télécharger une version qui correspond normalement à ce que tu recherches à cette adresse http://zigazou.free.fr/blog/scangrisversblanc.scm

Analyse le code et n’hésites pas à poser des questions si certains points te paraissent obscurs.

Concernant les bugs de ton code, il y en a effectivement beaucoup…

Ils sont dûs principalement au fait que tu abordes TinyScheme comme un langage procédural traditionnel, ce qu’il n’est pas ! (ex : (posclair=abs(posclair/3) ou lorsque tu cherches à convertir un while des familles).

Il y a aussi le fait que TinyScheme nécessite une grande rigueur quant aux parenthèses car on se perd très vite dans leur nombre et dans leur position.

Enfin le manque de maîtrise des différentes structures de TinyScheme (listes, tableaux etc.) et de Gimp (colormap, image, drawable etc.) n’arrange pas les choses.

Il n’y a donc rien d’étonnant à ce que tu te sois noyé dans ce maelström incompréhensible de parenthèses.

2 09 2010
Tibo

Merci beaucoup !

Je pense que ton script fonctionne, en effet j’ai fait beaucoup d’erreurs, mais je vais changer de session et ouvrir ubuntu pour le tester car je ne sais pas le faire avec windows…

à+

9 09 2010
Tibo

Coucou ! j’ai essayé le script : ça fonctionne !

En fait j’ai vu par hasard que si j’ouvrai toujours une image png avec le même nombre de couleur ça fonctionnait mais pas autrement car j’ai du enlever le convert-indexed qui me renvoyait toujours des erreurs…

Mais j’ai vu dans le navigateur de procédures que gimp-image-get-colormap recevai 2 paramètres : colormap que l’on utilise déjà et num-bytes. j’ai essayé d’intégrer ce paramètre pour ne plus avoir à changer le nombre de couleurs en hard dans le script et donc ne plus être obligé d’avoir des images avec le même nombre de couleurs mais je n’y arrive pas :

c’est une histoire de déclaration d’une variable b puis on fait bb=b/3 comme indiqué dans le navigateur de procédures pour avoir le nombre de couleurs et on insère :
(gimp-image-set-colormap image (* bb 3) tableau)
enfin je pense… le problème est que je suis tellement débutant que je n’y arrive pas 😦

ça ne presse pas, et déjà merci pour tout ce que tu m’as évité comme manip 🙂 !!

P.S. comme convert-indexed ne fonctionne pas, j’ai voulu simplement transformer la couleur la plus claire de mes png et ne plus convertir les jpg.

Laisser un commentaire