Besoin d'aide

Gimp est le fabuleux logiciel open source de dessin 2D de qualité professionnelle.
Répondre
Tader
Messages : 1
Inscription : 26 nov. 2012, 12:36

Besoin d'aide

Message par Tader »

Slt à tous,

Je suis sur gimp 2.8 et je voudrais savoir si c'est possible d'avoir un script qui pourra faire les choses suivante sur un serveur dont je suis l'admin:
1 - Se connecter sur le serveur via gimp
2 - prendre les photos, noms et prénoms, la date de naissance de chaque personnes sur le serveur
3 - puis les attribuer un modèle de carte de membre que j'ai céer sur gimp
4 - Et attribuer à ttes les photos un même format et la même dimension.
Je compte sur votre aide.
Merci d'avance!
Gimphried
Messages : 65
Inscription : 21 mai 2020, 16:52

Gimp Script-Fu : générateur de carte de membres

Message par Gimphried »

Bonjour,

Le titre est primordial pour attirer les lecteurs :

Gimp Script-Fu : générateur de carte de membres
Tader a écrit :1 - Se connecter sur le serveur via gimp
La seule chose que l'on sait c'est que vous êtes l'admin de ce serveur.
Cependant, le lecteur ne peut pas deviner si c'est un serveur de fichiers, un serveur Web ou beaucoup plus rarement un serveur Script-Fu pour GIMP sur un port dédié.

Par curiosité, consulter l'aide de Gimp et son protocole particulier :
10.6. Le sous-menu « Script-Fu »
10.6.4. Démarrer le serveur

Pour simplifier, considérons qu'il s'agit d'un serveur de fichiers. Il est équivalent au chemin local racine du projet :

Code : Tout sélectionner

C:/Tool/Gimp/forum/Linuxgraphic/GenCards/
Sous ce dossier racine, vous devez créer deux sous-dossiers :
  • le dossier source "icon" que le script va lire ;
  • le dossier cible vide "card" que le script va remplir.
Les informations au bout du chemin "icon" sont de nature :
  • textuelle : nom, prénom, date de naissance sous forme du nom de l'icône.
  • image : icône de la personne ;
    => Dans Gimp, créer l'icône bleue foncé RGB "0e11aa" de dimensions 120 x 158 pixels :
    1. Gimp menu "Fichier" > "Nouvelle image..."
    2. Dans la dlgbox "Créer une nouvelle image",
      Largeur : 120
      Hauteur : 158 px
      Clic btn "Valider"
    3. Dans la "Boîte à outils", clic petit rectangle coloré "La couleur de premier plan active"
      Dans la dlgbox "Modification de la couleur de premier plan", zone "Notation HTML", coller "0e11aa" et valider par Entrée.
      Clic btn "Valider"
    4. Dans la "Boîte à outils", clic "Outil de remplissage". Avec le pointeur souris, viser l'intérieur du rectangle vide de l'image créée. Clic.
      => le rectangle de l'icône est coloré en bleu foncé.
    5. Gimp menu "Fichier" > "Exporter sous" au format .jpg dans "C:/Tool/Gimp/forum/Linuxgraphic/GenCards/icon/last_first_DD_MM_YYYY.jpg"
Si les informations textuelles sont dans une feuille de calcul comme Calc ou une base de données, bing.com "LibreOffice publipostage".

L'objectif du projet est de générer la carte de membres de chaque personne du dossier "icon" dans la cible "card".

Adoptons les spécifications suivantes :
  • toutes les icones de personnes sont normalisées 120 x 158 pixels en .jpg dans le dossier "icon"
  • nom d'icône par personne nom + "_" + prénom + "_" + date. Par exemple : last_first_DD_MM_YYYY.jpg
  • gabarit de la carte de membre dans le dossier racine :
    => Dans Gimp, créer le gabarit minimal en bleu clair RGB "b5e8ec" de dimensions 396 x 274 pixels.
    Bien sûr, vous pouvez améliorer votre gabarit comme vous voulez.
    Il faut que le texte du nom, prénom, date qui va être affiché en noir dans la carte personnalisée soit lisible sur le fond bleu.
    Exporter au format .jpg dans "C:/Tool/Gimp/forum/Linuxgraphic/GenCards/memberCard.jpg"
Restaurer la couleur de premier plan noire RGB "000000" et d'arrière-plan blanche RGB "ffffff".
Fermer Gimp.
Réouvrir Gimp afin de réinitialiser les handles d'image et de calque.
Dernière modification par Gimphried le 26 mai 2020, 21:43, modifié 1 fois.
Gimphried
Messages : 65
Inscription : 21 mai 2020, 16:52

Comment développer en TinyScheme Script-Fu dans Gimp ?

Message par Gimphried »

Comment développer en TinyScheme Script-Fu dans Gimp ?
  1. Gimp menu "Filtres" > "Script-Fu" > "Console"
    => Disposer au mieux les fenêtres en évitant si possible leurs chevauchements.
  2. Dans la console Script-Fu, sous la zone de saisie, clic btn "Aide"
    => Le chapitre "10.6.3. Console Script-fu" s'affiche.
    • Consulter la figure 16.248 immédiatement dessous -- notamment la flèche verte -- qui indique que le résultat d'une validation par "Entrée" sera affiché au-dessus de la zone de saisie.
    • En colonne gauche, expanser l'arbre de navigation "II. Du débutant à l'expert" > "13. Compléter GIMP" > dbclick "3. Didacticiel pour Script-Fu".
    • Clic "=>" la flèche vers la droite dans le bandeau noir du bas de page.
    • Lire en diagonale jusqu'à "3.5.1. Création d'une nouvelle image et comparer avec le tuto.
      => Ce tuto reprend le didacticiel officiel en mettant à jour certaines fonctions obsolètes.
      Il simplifie la lecture notamment en sautant la phase plus ou moins complexe de la registration non nécessaire dans ce tuto.
  3. A droite de la zone de saisie de la console Script-Fu, clic btn "Parcourir..." pour afficher PDB : Procédure DataBase, "Navigateur de procédures Script-Fu".
    => A chaque introduction d'une nouvelle fonction, synchroniser cette aide en collant la fonction dans la zone de recherche.
    PDB explique ce que fait la fonction et ses paramètres.
  4. L'expression Lisp à copier-coller a été saisie dans NotePad++ pour la coloration syntaxique
    => NotePad++ menu "Langage" > "S" > "Scheme"
    Comme les expressions Lisp ont déjà été vérifiées dans NotePad++, le lecteur les copie une par une dans le presse-papier depuis ce tuto.
  5. Coller l'expression Lisp "(gimp-version)" sans les double quotes dans la zone de saisie de la console Script-Fu et valider par "Entrée" au clavier :
    Pour rappel : doc Gimp Figure 13.3. Utilisation de la console.
    => Script-Fu répond par la liste composée des éléments du numéro de version de Gimp : ("2.10.18")
Pour aller plus loin :
Choisissez votre aide pour le R5RS (Revised5 Report on Scheme), le standard de TinyScheme Script-Fu dans Gimp.
Pour Windows 10, l'aide r5rs.chm 248 Ko est la plus pratique.
Gimphried
Messages : 65
Inscription : 21 mai 2020, 16:52

Analyse syntaxique du nom d'une image

Message par Gimphried »

Analyse syntaxique du nom d'une image

Définir le chemin racine du projet en local sur votre disque dur :
  • Copier dans le presse-papier (Ctrl+C) l'expression lisp ci-dessous.
  • Coller (Ctrl+V) dans la zone de saisie de Script-Fu et valider par Entrée au clavier.

Code : Tout sélectionner

(define pathRoot "C:/Tool/Gimp/forum/Linuxgraphic/GenCards/")
pathRoot

Quand Script-Fu renvoie le nom de la variable ou de la fonction, c'est que la syntaxe Lisp est correcte !
Par convention, il est terminé par un slash "/". Validons par Entrée le nom de la variable :

Code : Tout sélectionner

pathRoot
"C:/Tool/Gimp/forum/Linuxgraphic/GenCards/"

Partons du chemin complet d'une image d'une personne nommée Last First née le DD_MM_YYYY du dossier "icon".
Définir le fichier source d'entrée (input) :

Code : Tout sélectionner

(define filin (string-append pathRoot "icon/Last_First_DD_MM_YYYY.jpg"))
filin

Vérifier le contenu de la variable "filin" :

Code : Tout sélectionner

filin
"C:/Tool/Gimp/forum/Linuxgraphic/GenCards/icon/Last_First_DD_MM_YYYY.jpg"

Découper chaque élément du chemin.
strbreakup est défini dans C:\Program Files\GIMP\share\gimp\2.0\scripts\script-fu-compat.init Elle n'est pas connue de PDB.

Code : Tout sélectionner

(strbreakup filin "/")
("C:" "Tool" "Gimp" "forum" "Linuxgraphic" "GenCards" "icon" "Last_First_DD_MM_YYYY.jpg")

last-pair est définie dans C:\Program Files\GIMP\share\gimp\2.0\scripts\script-fu.init :

Code : Tout sélectionner

(define person (car (last-pair (strbreakup filin "/"))))
person

Code : Tout sélectionner

person
"Last_First_DD_MM_YYYY.jpg"

Plutôt que surcharger la commande suivante, réutiliser le résultat précédent pour couper l'extension de fichier qui suit le "." :

Code : Tout sélectionner

(strbreakup person ".")
("Last_First_DD_MM_YYYY" "jpg")

Découper (tokeniser) chaque information textuelle selon le séparateur "_" :

Code : Tout sélectionner

(strbreakup (car (strbreakup person ".")) "_")
("Last" "First" "DD" "MM" "YYYY")
  • Le nom :

    Code : Tout sélectionner

    (define lastName (car (strbreakup (car (strbreakup person ".")) "_")))
    lastName

    Code : Tout sélectionner

    lastName
    "Last"
  • Le prénom :

    Code : Tout sélectionner

    (define firstName (cadr (strbreakup (car (strbreakup person ".")) "_")))
    firstName

    Code : Tout sélectionner

    firstName
    "First"
  • Reconstituer la date de naissance avec des slashes séparateurs :

    Code : Tout sélectionner

    (define dateBorn (unbreakupstr (cddr (strbreakup (car (strbreakup person ".")) "_")) "/"))
    dateBorn

    Code : Tout sélectionner

    dateBorn
    "DD/MM/YYYY"
Conclusion : l'analyse syntaxique du nom du fichier de l'image de la personne a permis de recomposer son nom, prénom et date de naissance.
Gimphried
Messages : 65
Inscription : 21 mai 2020, 16:52

Création de la première carte de membre vide selon gabarit

Message par Gimphried »

2. Création de la première carte de membre vide selon les dimensions du gabarit

La création de la première carte de membre est faite pas à pas au fur et à mesure de chaque copier-coller afin de les comprendre.

Code : Tout sélectionner

(define imgCard (car (gimp-image-new 396 274 RGB)))
renvoie imgCard. L'image n'est pas encore visible dans l'éditeur principal.
Notons que chaque procédure Gimp renvoie une liste.
=> Il faut donc appliquer la fonction "car" pour obtenir le premier élément de la liste.

Comme c'est la première image ouverte, imgCard vaut 1. C'est son id encore appelé handle.
Précédemment, nous avons fermé Gimp puis nous l'avons réouvert. Cela permet d'avoir comme premier handle libre 1.
Cependant, il ne faut pas présupposer de la valeur numérique des handles notamment en faisant des opérations arithmétiques sur les handles.

Code : Tout sélectionner

imgCard
1

Associer un calque (layer) à cette image sans opacité : 100 et afficher la valeur de layerCard.
Pour accélérer le tuto, copier-coller jusqu'à la fin de ligne après "layerCard" sans copier le retour-charriot.
Ainsi deux instructions sont copiées dans le presse-papier : la définition de la variable et l'affichage du contenu de la variable.

Code : Tout sélectionner

(define layerCard (car (gimp-layer-new imgCard 396 274 RGB-IMAGE "layer main" 100 LAYER-MODE-NORMAL-LEGACY)))
layerCard
layerCard2

Il faut interpréter ce double résultat par la définition a retourné layerCard et sa valeur est 2.
imgCard valant 1, layerCard vaut le prochain entier positif disponible soit 2.
Ne jamais présupposer que la handle layerCard vaut imgCard + 1.

Si vous obtenez "layerCard2#<EOF>", c'est que vous avez également copié-collé le retour-charriot après "layerCard".

L'erreur #<EOF> de fin de fichier étant générique, éviter cette erreur à tout prix.
Elle peut surtout signifier qu'il manque une parenthèse fermante que l'on peut longtemps chercher y compris dans NotePad++.
Fermer Gimp. Rouvrir Gimp et recommencer systématiquement les copiers-collers jusqu'à la suppression de l'erreur #<EOF>.

Positionner le calque au sommet de la pile des calques.

Code : Tout sélectionner

(gimp-image-insert-layer imgCard layerCard 0 0)
(#t)

#t signifie true : l'opération a été réalisée avec succès.
Pour l'instant rien ne s'affiche : ni dans l'éditeur principal, ni dans la fenêtre des calques.

Il est sous-entendu que vous avez synchronisé manuellement le navigateur PDB en recherchant la fonction "gimp-image-insert-layer" pour avoir l'explication parent = 0 et position = 0 comme derniers paramètres de la fonction.

Affichons l'image vide :

Code : Tout sélectionner

(gimp-display-new imgCard)
(1)

Renvoie l'id de l'image créée, c-a-d imgCard entre parenthèses.
L'image "[Sans titre]" peut apparaître comme un rectangle noir dans l'éditeur principal.

Copier-coller les trois instructions suivantes jusqu'à "BACKGROUND-FILL)" parenthèse fermante incluse.
Cela fixe la couleur d'avant-plan à noire '(0 0 0) et d'arrière-plan à blanche '(255 255 255).
Attention : ne jamais copier-coller le retour-charriot final.

Noter que les deux listes de couleurs RGB sont préfixées par une simple quote "'" pour considérer la liste comme littérale.
En l'absence de quote, TinyScheme interpréterait, après "(", le premier chiffre de couleur rouge (R)ed comme une fonction qui n'existe pas.

Code : Tout sélectionner

(gimp-context-set-foreground '(0 0 0)) ; black
(gimp-context-set-background '(255 255 255)) ; white
(gimp-drawable-fill layerCard BACKGROUND-FILL)
(#t)(#t)(#t)

Il y a autant de succès #t(rue) que de fonctions appelées.
Cependant si la console Script-Fu retourne "(#t)(#t)(#t)#<EOF>", c'est que vous avez --à tort-- copié-collé le retour-charriot après "BACKGROUND-FILL)".

Si l'image était noire, maintenant nous sommes sûr que son arrière-plan est blanc.

En colonne de droite, si l'onglet "Canaux" ou "Chemins" était sélectionné, cliquer sur l'onglet "Calques".
Notre premier calque apparaît dans la fenêtre des calques sous le nom voulu de "layer main".
Dernière modification par Gimphried le 26 mai 2020, 23:05, modifié 2 fois.
Gimphried
Messages : 65
Inscription : 21 mai 2020, 16:52

Insérer le fond d'image bleu ciel du gabarit minimal + texte

Message par Gimphried »

3. Insérer le fond d'image bleu ciel du gabarit minimal

Code : Tout sélectionner

(define imgTemplate (car (gimp-file-load-layer 1 imgCard "C:/Tool/Gimp/forum/Linuxgraphic/GenCards/memberCard.jpg")))
(gimp-image-insert-layer imgCard imgTemplate 0 0)
imgTemplate
imgTemplate(#t)5

Dans la fenêtre des calques est apparue memberCard.jpg au-dessus de "Layer main".

4. Insérer les trois textes

La fenêtre principale doit être visible pour voir en temps réel l'affichage des 3 textes suivant :

Code : Tout sélectionner

(gimp-text-fontname imgCard imgTemplate 140 50 lastName  0 TRUE 18 POINTS "Sans")
(gimp-text-fontname imgCard imgTemplate 140 70 firstName 0 TRUE 18 POINTS "Sans")
(gimp-floating-sel-anchor (car (gimp-text-fontname imgCard imgTemplate 140 90 dateBorn 0 TRUE 18 POINTS "Sans")))
(6)(7)(#t)

Le texte s'affiche en marge x = 140 px supérieur à la largeur de l'icône de la photo de la personne de 120 px.
Avec une taille de 18 points, il a été choisi un incrément de 20 pixels partant de 50, puis 70 et enfin 90 sur la coordonnée y.

A chaque insertion de texte, le texte devient clignotant sous forme de sélection flottante annulant le clignotement du précédent texte.
Annuler le clignotement d'une sélection flottante, c'est ancrer le texte dans un calque.
C'est pourquoi pour le dernier texte de la date de naissance, son id (ou handle) est passé explicitement à gimp-floating-sel-anchor pour l'ancrer.
Car il n'y a pas d'autres textes à afficher.
Dernière modification par Gimphried le 26 mai 2020, 23:06, modifié 1 fois.
Gimphried
Messages : 65
Inscription : 21 mai 2020, 16:52

Insérer l'icone de la personne, fusion de calques, export

Message par Gimphried »

5. Insertion de l'image de la personne représentée par son icone bleue foncé

Code : Tout sélectionner

(define imgIcon (car (gimp-file-load-layer RUN-NONINTERACTIVE imgCard "C:/Tool/Gimp/forum/Linuxgraphic/GenCards/icon/last_first_DD_MM_YYYY.jpg")))
(gimp-image-insert-layer imgCard imgIcon 0 0)
(gimp-layer-set-offsets imgIcon 10 10)
imgIcon(#t)(#t)

Initialement positionnée dans le coin supérieur gauche, l'icône est décalée en 10, 10 pour laisser un bord tout autour.

6. Fusionner les calques en un seul

Noter la réutilisation de la variable layerCard :

Code : Tout sélectionner

(define layerCard (car (gimp-image-flatten imgCard))
(12)

Les trois calques de l'icône, du gabarit et celui principal sont fusionnés en "Layer 1".

7. Exporter l'image finale dans le dossier "card"

Définir le nom du fichier cible de sortie (output) dans le dossier "card" qui doit exister.
=> Attention de pas écraser l'icône d'origine du dossier "icon".
Noter que l'on a supprimé l'information de date de naissance du nom cible.

Code : Tout sélectionner

(define filout (string-append pathRoot "card/" lastName "_" firstName ".jpg"))
filout
filout"C:/Tool/Gimp/forum/Linuxgraphic/GenCards/card/last_first.jpg"

Créer la carte de membre finale dans "card" et fermer l'image de l'éditeur Gimp ;

Code : Tout sélectionner

(file-jpeg-save RUN-NONINTERACTIVE imgCard layerCard filout filout 0.8 0 1 1 "" 2 1 0 0)
(gimp-image-clean-all imgCard)
(gimp-display-delete imgCard)
(#t)

Conclusion, la première carte de membre Last_First.jpg 6 Ko a été créée avec succès dans "card".
Fermer Gimp.
Dernière modification par Gimphried le 26 mai 2020, 23:34, modifié 1 fois.
Gimphried
Messages : 65
Inscription : 21 mai 2020, 16:52

Synthèse GenCard : les variables locales + debug

Message par Gimphried »

8. Synthèse GenCard, génération d'une carte de membre : les variables locales

Rouvrir Gimp. Pour les courageux qui suivent, nous repartons de zéro.

La structure de la fonction "let*" est en deux parties :
  • la déclaration des variables locales ;
  • le corps de la fonction constitué au début de "display" pour mise au point.
Attention de bien coller "let" et "*" sans espace entre eux.
Les handles d'images imgCard, layerCard, imgTemplate, imgIcon sont initialisés à zéro.

Code : Tout sélectionner

(define (GenCard pathRoot)
    (let*   (   (picIcon    "last_first_DD_MM_YYYY.jpg") ; temporary first icon
                (filin      (string-append pathRoot "icon/" picIcon)) ; source
                (person     (car (last-pair (strbreakup filin "/"))))
                (basename   (strbreakup (car (strbreakup person ".")) "_"))
                (lastName   (car  basename))
                (firstName  (cadr basename))
                (dateBorn   (unbreakupstr (cddr basename) "/"))
                (template   (string-append pathRoot "memberCard.jpg"))
                (filout     (string-append pathRoot "card/" lastName "_" firstName ".jpg")) ; target
                (imgCard 0)(layerCard 0)(imgTemplate 0)(imgIcon 0)
            ) ; end of local variables
        (display "picIcon: ")   (display picIcon)   (newline)
        (display "filin: ")     (display filin)     (newline)
        (display "person: ")    (display person)    (newline)
        (display "basename: ")  (display basename)  (newline)
        (display "lastName: ")  (display lastName)  (newline)
        (display "firstName: ") (display firstName) (newline)
        (display "dateBorn: ")  (display dateBorn)  (newline)
        (display "template: ")  (display template)  (newline)
        (display "filout: ")    (display filout)    (newline)
    ) ; always check the vertical alignement and the red color of let* end in NotePad++
)
GenCard

Script-Fu renvoie le nom de la fonction "GenCard" avec succès.
Ouf ! On ne s'est pas pris l'erreur "#<EOF>".
Sinon vérifier que vous n'avez pas copié-collé le retour-charriot final après la dernière parenthèse fermante.

Cela veut dire que chaque fin de ligne a été scrupuleusement vérifiée dans NotePad++ au niveau de l'équilibrage des parenthèses.
C'est extrêmement difficile à faire dans Script-Fu sans la coloration syntaxique de NotePad++.

Appeler votre fonction avec le chemin racine se terminant par un slash :

Code : Tout sélectionner

(GenCard "C:/Tool/Gimp/forum/Linuxgraphic/GenCards/")
picIcon: Last_First_DD_MM_YYYY.jpg
filin: C:/Tool/Gimp/forum/Linuxgraphic/GenCards/icon/Last_First_DD_MM_YYYY.jpg
person: Last_First_DD_MM_YYYY.jpg
basename: (Last First DD MM YYYY)
lastName: Last
firstName: First
dateBorn: DD/MM/YYYY
template: C:/Tool/Gimp/forum/Linuxgraphic/GenCards/memberCard.jpg
filout: C:/Tool/Gimp/forum/Linuxgraphic/GenCards/card/Last_First.jpg
#t

En conclusion, display et newline permettent de tracer un minimum le contenu des variables pour le debug.
Dernière modification par Gimphried le 26 mai 2020, 23:33, modifié 1 fois.
Gimphried
Messages : 65
Inscription : 21 mai 2020, 16:52

Synthèse GenCard : le corps de let* pour piloter Gimp

Message par Gimphried »

9. Synthèse GenCard, génération d'une carte de membre : pilotage de Gimp

Remplacer les "display" de debug par le pilotage de Gimp selon les étapes précédentes.
Reprendre chaque "define" de variables des pas à pas précédents et les remplacer par "set!".

Code : Tout sélectionner

(define (GenCard pathRoot)
    (let*   (   (filin      (string-append pathRoot "icon/last_first_DD_MM_YYYY.jpg")) ; source
                (person     (car (last-pair (strbreakup filin "/"))))
                (basename   (strbreakup (car (strbreakup person ".")) "_"))
                (lastName   (car  basename))
                (firstName  (cadr basename))
                (dateBorn   (unbreakupstr (cddr basename) "/"))
                (template   (string-append pathRoot "memberCard.jpg"))
                (filout     (string-append pathRoot "card/" lastName "_" firstName ".jpg")) ; target
                (imgCard 0)(layerCard 0)(imgTemplate 0)(imgIcon 0)
            ) ; end of local variables
        (set! imgCard (car (gimp-image-new 396 274 RGB)))
        (set! layerCard (car (gimp-layer-new imgCard 396 274 RGB-IMAGE "layer main" 100 LAYER-MODE-NORMAL-LEGACY)))
        (gimp-image-insert-layer imgCard layerCard 0 0) ; top of layer stack
        
        (gimp-display-new imgCard) ; display picture in the GUI
        
        (gimp-context-set-foreground '(0 0 0)) ; black
        (gimp-context-set-background '(255 255 255)) ; white
        (gimp-drawable-fill layerCard BACKGROUND-FILL)
        (set! imgTemplate (car (gimp-file-load-layer 1 imgCard template)))
        (gimp-image-insert-layer imgCard imgTemplate 0 0) ; add template layer
        (gimp-text-fontname imgCard imgTemplate 140 50 lastName  0 TRUE 18 POINTS "Sans")
        (gimp-text-fontname imgCard imgTemplate 140 70 firstName 0 TRUE 18 POINTS "Sans")
        (gimp-floating-sel-anchor (car (gimp-text-fontname imgCard imgTemplate 140 90 dateBorn 0 TRUE 18 POINTS "Sans")))
        (set! imgIcon (car (gimp-file-load-layer RUN-NONINTERACTIVE imgCard filin)))
        (gimp-image-insert-layer imgCard imgIcon 0 0) ; add icon layer
        (gimp-layer-set-offsets imgIcon 10 10)        ; shift icon to add border
        (set! layerCard (car (gimp-image-flatten imgCard))) ; merge layers
        (file-jpeg-save RUN-NONINTERACTIVE imgCard layerCard filout filout 0.8 0 1 1 "" 2 1 0 0)
        (gimp-image-clean-all imgCard)
        (gimp-display-delete imgCard)
    ) ; Check vertical alignement and red color of let* closing parenthesis in NotePad++
)
GenCard

Avant de tester GenCard, effacer le fichier résultat last_first.jpg dans la cible "card".

Code : Tout sélectionner

(GenCard "C:/Tool/Gimp/forum/Linuxgraphic/GenCards/")
(#t)

La barre de status de Gimp indique :
"Exportation de C:/Tool/Gimp/forum/Linuxgraphic/GenCards/card/last_first.jpg"

last_first.jpg 6 Ko a été recréé avec succès dans "card".
Gimphried
Messages : 65
Inscription : 21 mai 2020, 16:52

GenCard : optimisation RUN-NONINTERACTIVE sans le GUI de Gim

Message par Gimphried »

10. Génération d'une carte de membre : optimisation RUN-NONINTERACTIVE

L'optimisation consiste à ne pas afficher d'image dans le GUI (Graphic User Interface), c-a-d dans l'éditeur principal d'image de Gimp.
Cet affichage avait été utile pour suivre et comprendre visuellement le pas à pas.

En mode RUN-NONINTERACTIVE, il n'est plus nécessaire de passer par le GUI.
Mettons en commentaire "(gimp-display-new imgCard)" en préfixant par un point-virgule.

Idem pour la dernière instruction "(gimp-display-delete imgCard)".
Ajouter en remplacement "(gimp-image-delete imgCard)".

De plus comme tout se passe maintenant en mode invisible, remplaçons les constantes 396 x 274 pixels en dur lors de la création de l'image principale par une image minimale de 1 x 1 pixel.
Une fois le gabarit chargé, retaillons l'image finale avec le gabarit.
Le script devient plus générique quand on remplace les constantes en dur par des constantes nommées ou mieux par des variables calculées.

Code : Tout sélectionner

(define (GenCard pathRoot)
    (let*   (   (filin      (string-append pathRoot "icon/last_first_DD_MM_YYYY.jpg")) ; source
                (person     (car (last-pair (strbreakup filin "/"))))
                (basename   (strbreakup (car (strbreakup person ".")) "_"))
                (lastName   (car  basename))
                (firstName  (cadr basename))
                (dateBorn   (unbreakupstr (cddr basename) "/"))
                (template   (string-append pathRoot "memberCard.jpg"))
                (filout     (string-append pathRoot "card/" lastName "_" firstName ".jpg")) ; target
                (imgCard 0)(layerCard 0)(imgTemplate 0)(imgIcon 0)
            ) ; end of local variables
        (set! imgCard (car (gimp-image-new 1 1 RGB)))
        (set! layerCard (car (gimp-layer-new imgCard 1 1 RGB-IMAGE "layer main" 100 LAYER-MODE-NORMAL-LEGACY)))
        (gimp-image-insert-layer imgCard layerCard 0 0) ; top of layer stack
        
        ;(gimp-display-new imgCard) ; display picture in the GUI
        
        (gimp-context-set-foreground '(0 0 0)) ; black
        (gimp-context-set-background '(255 255 255)) ; white
        (gimp-drawable-fill layerCard BACKGROUND-FILL)
        (set! imgTemplate (car (gimp-file-load-layer 1 imgCard template)))              
        (gimp-image-insert-layer imgCard imgTemplate 0 0) ; add template layer
        
        (script-fu-util-image-resize-from-layer imgCard imgTemplate)
        (gimp-layer-resize-to-image-size layerCard) 
        
        (gimp-text-fontname imgCard imgTemplate 140 50 lastName  0 TRUE 18 POINTS "Sans")
        (gimp-text-fontname imgCard imgTemplate 140 70 firstName 0 TRUE 18 POINTS "Sans")
        (gimp-floating-sel-anchor (car (gimp-text-fontname imgCard imgTemplate 140 90 dateBorn 0 TRUE 18 POINTS "Sans")))
        (set! imgIcon (car (gimp-file-load-layer RUN-NONINTERACTIVE imgCard filin)))
        (gimp-image-insert-layer imgCard imgIcon 0 0) ; add icon layer
        (gimp-layer-set-offsets imgIcon 10 10)        ; shift icon to add border
        (set! layerCard (car (gimp-image-flatten imgCard))) ; merge layers
        (file-jpeg-save RUN-NONINTERACTIVE imgCard layerCard filout filout 0.8 0 1 1 "" 2 1 0 0)
        (gimp-image-clean-all imgCard)
        
        ;(gimp-display-delete imgCard) ; optimized by the following closing:
        (gimp-image-delete imgCard)
    ) ; Check vertical alignement and red color of let* closing parenthesis in NotePad++
)
L'exécution peut apparaître comme plus rapide sans l'affichage dans le GUI.
L'inconvénient est que pour la mise au point, il n'y a plus rien à voir dans l'éditeur principal de Gimp.
Gimphried
Messages : 65
Inscription : 21 mai 2020, 16:52

GenCards : généralisation file-glob(al) sur dossier "icon"

Message par Gimphried »

11. Boucler pour toutes les personnes du dossier "icon"

Créons une seconde personne dans "icon" par copier-coller de l'icône bleu foncé existante que l'on renomme "Nom_Prenom_JJ_MM_AAAA.jpg".

Code : Tout sélectionner

(file-glob "C:\\Tool\\Gimp\\forum\\Linuxgraphic\\GenCards\\icon\\*.jpg" 1)
(2 ("C:\\Tool\\Gimp\\forum\\Linuxgraphic\\GenCards\\icon\\last_first_DD_MM_YYYY.jpg" "C:\\Tool\\Gimp\\forum\\Linuxgraphic\\GenCards\\icon\\Nom_Prenom_JJ_MM_AAAA.jpg"))

Cependant avec des slashes Linux, file-glob ne comprend plus :

Code : Tout sélectionner

(file-glob "C:/Tool/Gimp/forum/Linuxgraphic/GenCards/icon/*.jpg" 1)
(0 ())

Introduisons string-replace :

Code : Tout sélectionner

; https://stackoverflow.com/questions/11509500/string-replace-in-gimp-script-fu
; Replace, in the string strWhere, the pattern strWhat with strWith
;                        ^ remains unmodified
(define (string-replace strWhere strWhat strWith)
    (let*   (   (lenWhat  (string-length strWhat))
                (lenWith  (pred (string-length strWith)))
                (lenWhere (string-length strWhere))
                (result strWhere)
            )
        (let loop ((curIndex 0))        
            (if (<= (+ curIndex lenWhat) lenWhere) ; loop through the main string searching for the substring
                (begin
                    (if (substring-equal? strWhat result curIndex (+ curIndex lenWhat)) ; check to see if the substring is a match
                        (begin
                            (set! result (string-append (substring result 0 curIndex) strWith (substring result (+ curIndex lenWhat) lenWhere))) ;create the result string
                            (set! curIndex (+ curIndex lenWith)) ; current index to the end of the replacement
                            (set! lenWhere (string-length result)) ; new length for lenWhere so we can accurately grab what we need
                        )
                    )
                    (loop (+ curIndex 1))
                )
            )
        )
       result
    )
)

Code : Tout sélectionner

(file-glob (string-replace "C:/Tool/Gimp/forum/Linuxgraphic/GenCards/icon/*.jpg" "/" "\\") 1)
(2 ("C:\\Tool\\Gimp\\forum\\Linuxgraphic\\GenCards\\icon\\last_first_DD_MM_YYYY.jpg" "C:\\Tool\\Gimp\\forum\\Linuxgraphic\\GenCards\\icon\\Nom_Prenom_JJ_MM_AAAA.jpg"))

Contrairement à l'officiel file-glob, notre file-global retourne directement la liste des fichiers correspondant au pattern.
Alors que file-glob retourne une liste commençant par le nombre d'item de la sous-liste qui suit.

Code : Tout sélectionner

(define (file-global strPath)
    (let*   (   (lstFile (file-glob strPath 1))
            )
        (if (zero? (car lstFile))
            (begin ; Linux to Windows path translation
                (set! lstFile (file-glob (string-replace strPath "/" "\\") 1))
                (if (zero? (car lstFile)) 
                    () ; no files match the pattern
                    ; Windows to Linux path translation
                    (map (lambda (path) (string-replace path "\\" "/")) (cadr lstFile))
                )
            )
            (cadr lstFile) ; original filename list supplied by file-glob
        )
    )
)

Code : Tout sélectionner

(file-global "C:/Tool/Gimp/forum/Linuxgraphic/GenCards/icon/*.jpg")
("C:/Tool/Gimp/forum/Linuxgraphic/GenCards/icon/last_first_DD_MM_YYYY.jpg" "C:/Tool/Gimp/forum/Linuxgraphic/GenCards/icon/Nom_Prenom_JJ_MM_AAAA.jpg")

Dans la version finale de GenCard, filin est remonté en paramètre.
Les constantes en dur sont remplacées par les variables locales : posX, posY, incrY.
imgCard et layerCard sont retaillées selon le gabarit imgTemplate.

Code : Tout sélectionner

(define (GenCard pathRoot filin)
    (let*   (   (person     (car (last-pair (strbreakup filin "/"))))
                (basename   (strbreakup (car (strbreakup person ".")) "_"))
                (lastName   (car  basename)) (posX 140) (posY 50) (incrY 20)
                (firstName  (cadr basename))
                (dateBorn   (unbreakupstr (cddr basename) "/"))
                (template   (string-append pathRoot "memberCard.jpg"))
                (filout     (string-append pathRoot "card/" lastName "_" firstName ".jpg")) ; target
                (imgCard 0)(layerCard 0)(imgTemplate 0)(imgIcon 0)
            ) ; end of local variables
        (set! imgCard (car (gimp-image-new 1 1 RGB)))
        (set! layerCard (car (gimp-layer-new imgCard 1 1 RGB-IMAGE "layer main" 100 LAYER-MODE-NORMAL-LEGACY)))
        (gimp-image-insert-layer imgCard layerCard 0 0) ; top of layer stack
        (gimp-context-set-foreground '(0 0 0)) ; black
        (gimp-context-set-background '(255 255 255)) ; white
        (gimp-drawable-fill layerCard BACKGROUND-FILL)
        (set! imgTemplate (car (gimp-file-load-layer 1 imgCard template)))              
        (gimp-image-insert-layer imgCard imgTemplate 0 0) ; add template layer
        
        (script-fu-util-image-resize-from-layer imgCard imgTemplate)
        (gimp-layer-resize-to-image-size layerCard) 
        
        (gimp-text-fontname imgCard imgTemplate posX posY lastName  0 TRUE 18 POINTS "Sans")
        (set! posY (+ posY incrY))
        (gimp-text-fontname imgCard imgTemplate posX posY firstName 0 TRUE 18 POINTS "Sans")
        (gimp-floating-sel-anchor (car (gimp-text-fontname imgCard imgTemplate posX (+ posY incrY) dateBorn 0 TRUE 18 POINTS "Sans")))
        (set! imgIcon (car (gimp-file-load-layer RUN-NONINTERACTIVE imgCard filin)))
        (gimp-image-insert-layer imgCard imgIcon 0 0) ; add icon layer
        (gimp-layer-set-offsets imgIcon 10 10)        ; shift icon to add border
        (set! layerCard (car (gimp-image-flatten imgCard))) ; merge layers
        (file-jpeg-save RUN-NONINTERACTIVE imgCard layerCard filout filout 0.8 0 1 1 "" 2 1 0 0)
        (gimp-image-clean-all imgCard)      
        (gimp-image-delete imgCard)
    ) ; Check vertical alignement and red color of let* closing parenthesis in NotePad++
)
GenCard

La différence entre "let*" et "let loop", c'est que "let*" introduit des variables locales.

"let loop" introduit ci-dessous une liste locale "listFile" ainsi qu'une boucle sur cette liste.
La structure classique est de tester par "if (pair? listFile)" si la liste n'est pas vide.
Dans ce cas, le traitement (GenCard pathRoot (car listFile)) s'applique sur le 1er item.
Ensuite, boucler sur le reste des items de la liste.

Code : Tout sélectionner

(define (GenCards pathRoot)
    (let*   (   (pattern (string-append pathRoot "icon/*.jpg")) ; source
                (nbrCard 0)
            )
        (let loop   (   (listFile (file-global pattern)))
            (if (pair? listFile)
                (begin
                    (GenCard pathRoot (car listFile)) ; generate the member card
                    (set! nbrCard (+ nbrCard 1)) ; increment the nummber of cards
                    (loop (cdr listFile)) ; next cards
                )
            )
        )
        (display "GenCards generated successfully ") (display nbrCard) (display " cards!") (newline)
    )
)
GenCards

Code : Tout sélectionner

(GenCards "C:/Tool/Gimp/forum/Linuxgraphic/GenCards/")
GenCards generated successfully 2 cards!
#t

Le dossier "card" comprend bien deux cartes de membre :
  • last_first.jpg 6 Ko avec la date de naissance "DD/MM/YYYY" ;
  • Nom_Prenom.jpg 6 Ko avec la date de naissance "JJ/MM/AAAA".
Répondre