Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Add text with script fu
#5
Rainbow 
Hello Carlbcx,

Carlbcx Wrote:I'm working on a poster without date. I need, from this file, make 30 similar posters, just adding a different date to each one.

Chapter 1: Learning basic string operations in Script-Fu
  1. Run Gimp
  2. Gimp menu Filters > Scrip-Fu > Console
  3. Copy in the clipboard the following Script-Fu expression:
Code:
(string-append "C:\\Tool\\Gimp\\forum\\gimp-forum.net\\WriteDate" DIR-SEPARATOR "template" ".png")
  • Paste the content of the clipboard in the input area of the Script-Fu console.
  • Validate by ENTER.
;-> the result should be, in Windows, the full path of your poster:
"C:\\Tool\\Gimp\\forum\\gimp-forum.net\\WriteDate\\template.png"

In Linux, adapt the following path "/home/Tool/Gimp/gimp-forum.net/WriteDate" to your needs:
  • DIR-SEPARATOR is "\\" in Windows
  • DIR-SEPARATOR is "/" in Linux

Consider that the path-in parameter is the root folder of the project called WriteDate.
path-in contains template.png that is to say the poster of reference.

The goal is to generate the dated posters in the subfolder target.
According to your operating system, you must create manually the target folder under path-in.

path-in  = C:\\Tool\\Gimp\\forum\\gimp-forum.net\\WriteDate
path-out = C:\\Tool\\Gimp\\forum\\gimp-forum.net\\WriteDate\\target

We generate the dated posters in the subfolder target in order to remove quickly its content before running again the script.

Regards.

Chapter 2: Defining and running your first Script-Fu function

Define your first Script-Fu function called GenFileOut.
let* introduces the initialization of local variables such as filePoster until file-out.
As usual, copy in the clipboard the following code and paste it in the Script-Fu console:
Code:
(define (GenFileOut path-in template ext date counter)
    (let*    (    (filePoster    (string-append path-in DIR-SEPARATOR template ext))
                (strIdx (number->string counter))
                (strZidx (if (< counter 10) (string-append "0" strIdx) strIdx))
                (path-out (string-append path-in DIR-SEPARATOR "target" DIR-SEPARATOR))
                (file-out (string-append path-out template strZidx ext))
            )
        (display "filePoster: ")    (displayln filePoster)        
        (display "strIdx: ")        (displayln strIdx)        
        (display "strZidx: ")        (displayln strZidx)        
        (display "path-out: ")        (displayln path-out)        
        (display "file-out: ")        (displayln file-out)
)    )
;-> the result of the Script-Fu console should be:
GenFileOut
meaning that your definition is ok. The aligned parenthesis are well balanced.

Run your first function.
We split the full path of the poster of reference as several parameters in order to avoid scanning and parsing the path.
Code:
(GenFileOut "C:\\Tool\\Gimp\\forum\\gimp-forum.net\\WriteDate" "template" ".png" "10/15/2021" 0)
;-> the result of the Script-Fu console should be:
Code:
filePoster: C:\Tool\Gimp\forum\gimp-forum.net\WriteDate\template.png
strIdx: 0
strZidx: 00
path-out: C:\Tool\Gimp\forum\gimp-forum.net\WriteDate\target\
file-out: C:\Tool\Gimp\forum\gimp-forum.net\WriteDate\target\template00.png#t
The return code #t of the function GenFileOut is concatenated with the file-out full path.

If displayln is unknown, it is normally defined in C:\Program Files\GIMP 2\share\gimp\2.0\scripts\palette-export.scm by:
Code:
(define displayln (lambda (obj) (display obj) (display "\n")))

The if instruction is followed by the condition, "Then" part and "Else" part.
In Pascal or Basic-like:
Code:
If counter < 10 then strZidx = "0" + strIdx Else strZidx = strIdx 
However the keywords "Then" and "Else" are implicit in Script-Fu:
Code:
(if (closure? GenFileOut)(display "GenFileOut is a known function")(display "GenFileOut is UNknown"))
;-> GenFileOut is a known function#t

Code:
(if (closure? 'rascalFiloute)(display "rascalFiloute is a known function")(display "rascalFiloute is UNknown"))
;-> will fail: rascalFiloute  Wink is UNknown#t

Chapter 3: WriteDate from template.png

Ofnuts Wrote:Doable with script-fu

We are ready to experiment our new function WriteDate.
Before running WriteDate, prepare with Gimp an empty square image 500 x 500 pixels of yellow color RGB ffff00
Gimp menu File> Export as "template.png" in your working folder "C:\\Tool\\Gimp\\forum\\gimp-forum.net\\WriteDate".

Code:
(define (WriteDate path-in template ext date counter)
    (let*    (    (filePoster    (string-append path-in DIR-SEPARATOR template ext))
                (strIdx (number->string counter))
                (strZidx (if (< counter 10) (string-append "0" strIdx) strIdx))
                (path-out (string-append path-in DIR-SEPARATOR "target" DIR-SEPARATOR))
                (file-out (string-append path-out template strZidx ext))
                (posX 100) (posY 100)
                (imgDat        (car (gimp-image-new 1 1 RGB))) ; Empty poster
                (layerDat     (car (gimp-layer-new imgDat 1 1 RGB-IMAGE "layer_date" 100 LAYER-MODE-NORMAL-LEGACY)))
            )
        (gimp-image-insert-layer imgDat layerDat 0 0)
        (gimp-context-set-foreground '(0 0 0)) ; black
        (gimp-context-set-background '(255 255 255)) ; white
        (gimp-drawable-fill layerDat BACKGROUND-FILL) ; Empty white poster
        (let* ((layerPoster (car (gimp-file-load-layer 1 imgDat filePoster)))) ; load template
            (gimp-image-insert-layer imgDat layerPoster 0 0) ; as a layer to the empty poster
            (script-fu-util-image-resize-from-layer imgDat layerPoster) ; same size than the template
            (gimp-layer-resize-to-image-size layerDat)
            (display "file-out: ") (display file-out) (display " date: ") (displayln date)
            ; Write the date in posX, posY Sans font (private joke)
            (let* ((layerTxt (car (gimp-text-fontname imgDat layerPoster posX posY date 0 TRUE 18 POINTS "Sans"))))
                (gimp-floating-sel-anchor layerTxt)
        )    ) ; Anchor the floating selection to its associated drawable
        (let* ((layerSav (car (gimp-image-flatten imgDat)))) ; Save the dated poster
            (gimp-displays-flush)
            (gimp-file-save RUN-NONINTERACTIVE imgDat layerSav file-out file-out)
            (gimp-image-delete imgDat)        
)    )    )
;-> the result of the Script-Fu console should be:
WriteDate

Code:
(WriteDate "C:\\Tool\\Gimp\\forum\\gimp-forum.net\\WriteDate" "template" ".png" "10/15/2021" 0)
;-> the result of execution should be:
file-out: C:\Tool\Gimp\forum\gimp-forum.net\WriteDate\target\template00.png date: 10/15/2021
(#t)

template00.png has been SUCCESSFULLY generated in the target folder.
We recognize the yellow square of template.png but with the written date "10/15/2021"!

Chapter 4: Basic iterator WriteDates

We wish to call WriteDate for each date of the given list: '("10/15/2021" "10/11/2021")
To get the first date:  Shy
Code:
(car '("10/15/2021" "10/11/2021"))
;-> "10/15/2021"

To get the remaining dates in a list:
Code:
(cdr '("10/15/2021" "10/11/2021"))
;-> ("10/11/2021")

car and cdr are the basic extractors of a Script-Fu list.

WriteDates is a basic iterator based on let loop that increments counter from idxStart = 0.

Note that we save the Gimp context by gimp-context-push because we change the fore and background colors.
We restore this context before the end by gimp-context-pop.

Before running WriteDates, remove manually all previously generated *.png from the target folder.
Code:
; Main iterator
(define (WriteDates path-in template ext lstDate idxStart)
    (gimp-context-push)
    (displayln "") (displayln "WriteDates is running...")
    (let loop ((lstStr lstDate) (counter idxStart))
        (if (pair? lstStr)
            (begin    (WriteDate path-in template ext (car lstStr) counter)
                    (loop (cdr lstStr) (+ counter 1))
            )
            (begin    (display  counter)
                    (displayln " posters have been SUCCESSFULLY generated!")
    )    )    )
    (gimp-context-pop)
)
;-> WriteDates

Let us generate two posters dated from the list of dates '("10/15/2021" "10/11/2021")

Code:
(WriteDates "C:\\Tool\\Gimp\\forum\\gimp-forum.net\\WriteDate" "template" ".png" '("10/15/2021" "10/11/2021") 0)
;-> generates template00.png dated "10/15/2021" and template01.png dated "11/10/2021" in the target folder.
WriteDates is running...
file-out: C:\Tool\Gimp\forum\gimp-forum.net\WriteDate\target\template00.png date: 10/15/2021
file-out: C:\Tool\Gimp\forum\gimp-forum.net\WriteDate\target\template01.png date: 10/11/2021
2 posters have been SUCCESSFULLY generated!
(#t)

Take in consideration that, in the if that checks if the list of dates is not empty,
the Then and Else parts have more than one statement. We need to encapsulated them in begin.

If you read this thread until here, it will be a first step in the Script-Fu world of another era.
Would you also share your experimentation with ImageMagick according to the rich2005's bash file?
Regards.
Reply


Messages In This Thread
Add text with script fu - by carlbcx - 09-01-2019, 03:09 PM
RE: Add text with script fu - by rich2005 - 09-01-2019, 05:28 PM
RE: Add text with script fu - by Ofnuts - 09-01-2019, 05:29 PM
RE: Add text with script fu - by carlbcx - 09-01-2019, 07:07 PM
1. Learning basic string operations in Script-Fu - by Gimphried - 10-15-2021, 08:53 PM
RE: Add text with script fu - by carlbcx - 09-04-2022, 10:29 AM
RE: Add text with script fu - by carlbcx - 09-04-2022, 12:35 PM

Forum Jump: