It is currently Sun Jun 30, 2024 5:32 am


All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 42 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Re: Shortening mouse/keystrokes save/export script or method to implem
PostPosted: Sat Apr 15, 2023 9:27 pm  (#11) 
Offline
GimpChat Member

Joined: Dec 27, 2022
Posts: 22
I would also mention a creature feature to help eliminate mouse clicking and typing would be for the .xcf file and exported png/jpg to pickup/use the folder name...in which....should already be named movie/tv show (date) and construct filenames based on that with the proper index concatenated.

So if I was building a clearart file located in a proper movie name like: After Earth (2013)

When the export is ready, it would generate the files:

After Earth (2013).xcf
After Earth (2013)-clearart.png

I was also thinking about the index 4, makes sense in this stage, a bonus would be when the save/export is called, that all of the art types are represented with checkboxes defaulted to FALSE and when you select a single only checkmark, it uses that checkmarks index to output the appropriate file naming convention.

I am looking at everything here and its a pretty sweet so far, thanks for the assist on this, it would have been very difficult to even get to where this is at now as I'm learning this from scratch. So thank you for your efforts.

Chris


Top
 Post subject: Re: Shortening mouse/keystrokes save/export script or method to implem
PostPosted: Sat Apr 15, 2023 10:05 pm  (#12) 
Offline
GimpChat Member

Joined: Dec 27, 2022
Posts: 22
I'm getting this error:

> (KodiSkinPath (gimp-image-get-id) (ReadKodiSaveArtType))
Error: eval: unbound variable: read-line

Using Windows 10.

TY.


Top
 Post subject: KodiSave 1.1 + I/O read-line
PostPosted: Sun Apr 16, 2023 6:11 am  (#13) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
kittmaster wrote:
Error: eval: unbound variable: read-line

KodiSave 1.1 + I/O read-line

I forgot read-line from the I/O library powered by Richard O'Keefe in the Indiana University Bloomington repository.
Because this library is included with credits in my GimpLambdaLib 0ts-stdio.scm

So I removed my entire GimpLambdaLib to keep only KodiSave.scm version 1.1 pusblished in GimpChat page 1.
read-line has been added at the end of this script. So you do not need to install the GimpLambdaLib.

I found that the Gimp status bar is very volatile. :shock:
The KodiSave message is often overwritten by any other messages if the user moves the mouse pointer.

Attachment:
KodiSaveWarning.png
KodiSaveWarning.png [ 80.44 KiB | Viewed 1660 times ]

So, in 1.1, the KodiSave message is also displayed in the Error console even if it is not an error.
To open the Gimp Error console, click Gimp menu "Windows" > "Dockable Dialogs" > "Error Console".
KodiSave will display its message of export in a persistent way until you clear the Error Console. :hi5

I will analyse your detailed requirements #10 and #11 soon.


Last edited by AlSchemist on Sun Apr 16, 2023 2:20 pm, edited 1 time in total.

Top
 Post subject: KodiSave 1.5 with art type dialog box
PostPosted: Sun Apr 16, 2023 1:54 pm  (#14) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
KodiSave 1.5 with dialog box for art type = clearart

KodiSave 1.5 with dialog box strongly simplifies the Scheme code since the text file KodiSaveArtType.txt is no longer required.
Hence the I/O library for Script-Fu has been removed.
However you would select the art type in the dlgbox if you wish to change it.

; script-fu-kodi-save.scm 1.5 saves the current image as .xcf and export as .png or .jpg
; according to the art type pulldown listbox selected in the dialog box
; Copyright (C) 2023 AlSchemist. All Rights Reserved.
; Line: 184 define: 8 comment: 65 = 35.3% blank: 10
; The following is free TinyScheme open source copyrighted AlSchemist developed for Gimp 2.10.34

; Vector of Kodi art types
; Zero-based artTypeIdx   0       1      2        3              4          5           6         7        8        9          10       11      12
(define vKodiArtSuffix #("actor" "back" "banner" "characterart" "clearart" "clearlogo" "discart" "fanart" "keyart" "landscape" "poster" "spine" "thumb"))
; vector of overlay boolean by art type: #t means .png otherwise #f stands for .jpg
(define vOverlay       #(#f      #f     #f       #t             #t         #t          #t        #f       #f       #f          #f       #f      #f))
(define idxFanArt                                                                                 7)

; Return the first element of lst
; Call the car primitive checking before if the list is not empty. Otherwise display the running context for debugging purpose
; (carDbg '(first rest) 'caller 'prm)
; first

; (carDbg '() 'caller 'prm)
; caller: prm
; Error: carDbg called with empty list
(define (carDbg lst caller prm)
   (if (pair? lst)
      (car lst)
      (begin
         (and (display caller)(display ": ")(displayln prm))
         (error "carDbg called with empty list")
)   )   )

; Display all art types defined in the vector vKodiArtSuffix
; (DisplayAllArtType)
; art type 0: actor 1: back 2: banner 3: characterart 4: clearart 5: clearlogo
; 6: discart 7: fanart 8: fanartSharp 9: keyart 10: landscape 11: poster 12: spine 13: thumb()
(define (DisplayAllArtType)
   (let*   (    (artTypeMax (vector-length vKodiArtSuffix))   ; index maximum in vKodiArtSuffix
         )
      (display "art type")
      (let loop ((idx 0)) ; starting 0-based index
         (if (< idx artTypeMax) ; Loop while the index does not reach the maximum
         (begin
            (if (= idx 6) (displayln "") (display " "))
            (display idx) (display ": ") (display (vector-ref vKodiArtSuffix idx))
            (loop (+ idx 1)) ; recursive call incrementing the index of art type
)   )   )   )   )

; Display all art types and the corresponding overlay predicate
; (DisplayOverlay)
; art type 0: actor no transparency as .jpg
; art type 1: back no transparency as .jpg
; art type 2: banner no transparency as .jpg
; art type 3: characterart transparent overlay as .png
; art type 4: clearart transparent overlay as .png
; art type 5: clearlogo transparent overlay as .png
; art type 6: discart transparent overlay as .png
; art type 7: fanart no transparency as .jpg
; art type 8: keyart no transparency as .jpg
; art type 9: landscape no transparency as .jpg
; art type 10: poster no transparency as .jpg
; art type 11: spine no transparency as .jpg
; art type 12: thumb no transparency as .jpg
; ()
(define (DisplayOverlay)
   (let*   (    (artTypeMax (vector-length vKodiArtSuffix))   ; index maximum in vKodiArtSuffix
            (overlayMax (vector-length vOverlay))
         )
      (if (<> artTypeMax overlayMax) (error "vKodiArtSuffix length does not match with vOverlay length"))
      (let loop ((idx 0)) ; starting 0-based index
         (if (< idx artTypeMax) ; Loop while the index does not reach the maximum
            (let*   (   (isPng?   (vector-ref vOverlay idx)))
               (display "art type ")
               (display idx) (display ": ") (display (vector-ref vKodiArtSuffix idx))
               (if isPng? (displayln " transparent overlay as .png") (displayln " no transparency as .jpg"))
               (loop (+ idx 1)) ; recursive call incrementing the index of art type
)   )   )   )   )

; Return the image id of the first currently loaded image
; (gimp-image-get-id)
; 1
(define (gimp-image-get-id)
   (let*   ((lstImg (gimp-image-list)))
      (if (zero? (carDbg lstImg 'gimp-image-get-id (gimp-image-list))) ; number of loaded image = 0?
         (error "3000. gimp-image-get-id: no image is open in Gimp.\nHow to fix it? Gimp menu \"File\" > \"Open\" > .webp or .png")
         (vector-ref (cadr lstImg) 0) ; the first loaded image
)   )   )

; Return the filename of img if it has been already saved.
; Otherwise the filename is empty. Search in the list of opened images if there is one which has been saved.
; If found, return its name
; Otherwise fire an error
; (SearchFilename (gimp-image-get-id))
(define (SearchFilename img)
   (let*   (    (fullname (carDbg (gimp-image-get-filename img) 'SearchFilename1 img)))
      (if (zero? (string-length fullname))
         (let*   (   (lstImg (gimp-image-list))
                  (vImg   (cadr lstImg))
                  (nbrImg   (carDbg lstImg 'SearchFilename2 (gimp-image-list)))
               )
            (let loop ((idx 0))
               (if (>= idx nbrImg) (error "SearchFilename cannot find any open image already saved!")
                  (let*   (   (picId   (vector-ref vImg idx))
                           (picNam (carDbg (gimp-image-get-filename picId) 'SearchFilename3 picId))
                        )
                     (if (and (<> picId img) (> (string-length picNam) 0))
                        picNam
                        (loop (+ idx 1))
         )   )   )   )   )
         fullname
)   )   )

; Returns a vector composed by the path, the basename and the file extension of the image having img as id
; (PathInfoPic (gimp-image-get-id))
; #("C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng" "iconAlSchemist" "png")
(define (PathInfoPic img)
   (let*   (    (fullname (SearchFilename img))
            (lstPath  (strbreakup fullname DIR-SEPARATOR)) ; split the fullname removing each DIR-SEPARATOR
            (lstDir   (reverse (cdr (reverse lstPath))))   ; remove the filename from lstPath
            (path     (unbreakupstr lstDir DIR-SEPARATOR)) ; Rebuild the path without the filename
            (filename (carDbg (last lstPath) 'PathInfoPic2  lstPath)) ; filename is the last string of lstPath
            (lstFile  (strbreakup filename ".")) ; split the filename into the basename and the fileExt
            (basename (carDbg lstFile 'PathInfoPic3 filename))
            (filExt   (carDbg (last lstFile) 'PathInfoPic4 filename)) ; without dot
         )
      (vector path basename filExt)
)   )

; Split path into drive, root and folder. path must not ends by DIR-SEPARATOR
; (PathSplit "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng")
; #("C:" "C:\\Tool\\Gimp\\forum\\GimpChat" "SaveXcf-ExportPng")
(define (PathSplit path)
   (let*   (    (lstPath  (strbreakup path DIR-SEPARATOR)) ; split the path removing each DIR-SEPARATOR
            (lstDir   (reverse (cdr (reverse lstPath))))   ; remove the last folder from lstPath
            (root     (unbreakupstr lstDir DIR-SEPARATOR)) ; Rebuild the root without the last folder
            (folder   (carDbg (last lstPath) 'PathSplit1 path)) ; folder is the last string of lstPath
            (drive    (carDbg lstPath 'PathSplit2 path))
         )
      (vector drive root folder)
)   )

; Return the full path of the image with Kodi skin suffix according to the artType index and fanArtNbr
; (KodiSkinPath "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng\\Movies\\Aliens (1986)" "Aliens (1986)" 4 0)
; "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng\\Movies\\Aliens (1986)\\Aliens (1986)-clearart.png"
; (KodiSkinPath "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng\\Movies\\Aliens (1986)" "Aliens (1986)" 9 0)
; "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng\\Movies\\Aliens (1986)\\Aliens (1986)-landscape.jpg
; (KodiSkinPath "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng\\Movies\\Aliens (1986)" "Aliens (1986)" 7 0)
; "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng\\Movies\\Aliens (1986)\\Aliens (1986)-fanart.jpg"
; (KodiSkinPath "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng\\Movies\\Aliens (1986)" "Aliens (1986)" 7 1)
; "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng\\Movies\\Aliens (1986)\\Aliens (1986)-fanart1.jpg"
; (KodiSkinPath "C:\\Movies\\Aliens (1986)" "Aliens (1986)" 7 5.6)
; "C:\\Movies\\Aliens (1986)\\Aliens (1986)-fanart6.jpg"
; (KodiSkinPath "C:\\Movies\\Aliens (1986)" "Aliens (1986)" 7 5.5)
; "C:\\Movies\\Aliens (1986)\\Aliens (1986)-fanart6.jpg"
; (KodiSkinPath "C:\\Movies\\Aliens (1986)" "Aliens (1986)" 7 5.1)
; "C:\\Movies\\Aliens (1986)\\Aliens (1986)-fanart5.jpg"
(define (KodiSkinPath path basename artTypeIdx fanArtNbr)
   (let*   (    (isPng?      (vector-ref vOverlay artTypeIdx))
            (filExt      (if isPng? ".png" ".jpg"))
            (intFanArt   (if (integer? fanArtNbr) fanArtNbr (trunc (round fanArtNbr))))
            (strFanArt   (carDbg (strbreakup (number->string intFanArt 10) ".") 'KodiSkinPath fanArtNbr))
            (filename   (if (and (= artTypeIdx idxFanArt) (> fanArtNbr 0))
                        (string-append basename "-" (vector-ref vKodiArtSuffix artTypeIdx) strFanArt filExt)
                        (string-append basename "-" (vector-ref vKodiArtSuffix artTypeIdx) filExt)
            )            )
            (fullname   (string-append path DIR-SEPARATOR filename))
         )
      fullname
)   )

; Open a picture in Gimp
; Then click "File" > "KodiSave" in the Save section
; Alternatively in the Script-Fu console without using any menu:
; (let*   ((img (gimp-image-get-id)) (layer (car (gimp-image-get-active-drawable img)))) (script-fu-kodi-save img layer 2 0))
(define (script-fu-kodi-save img layer artTypeIdx fanArtNbr)
   (let*   (    (vInfoPic (PathInfoPic img)) ; Split the full path of image in path, basename and extension
            (pathPic  (vector-ref vInfoPic 0)) ; 0-based element in the vector
            (vPath    (PathSplit pathPic)) ; Split the path in drive, root and folder
            (root     (vector-ref vPath 1))
            (folder   (vector-ref vPath 2))
            (fileXcf  (string-append folder ".xcf")) ; XCF has the folder as basename
            (fullXcf  (string-append pathPic DIR-SEPARATOR fileXcf))
            (fullSkin (KodiSkinPath pathPic folder artTypeIdx fanArtNbr))
            (isPng?   (vector-ref vOverlay artTypeIdx))
            (imgSkin  (carDbg (gimp-image-duplicate img) 'script-fu-kodi-save1 img)) ; Duplicate the current image
         )
      (gimp-xcf-save 0 img layer fullXcf fullXcf) ; Save the current image as XCF
      (let*   (   (imgXcf (carDbg (gimp-file-load RUN-NONINTERACTIVE fullXcf fullXcf) 'script-fu-kodi-save2 fullXcf)) ; Reload XCF
            )
         (gimp-displays-reconnect img imgXcf)
         (gimp-image-clean-all imgXcf)
         (gimp-image-merge-visible-layers imgSkin CLIP-TO-IMAGE) ; Merge all layers before saving as PNG
         (let*   ((layerSkin (carDbg (gimp-image-get-active-drawable imgSkin) 'script-fu-kodi-save3 imgSkin)))
            (if isPng?
               (file-png-save RUN-NONINTERACTIVE imgSkin layerSkin fullSkin fullSkin 0 9 0 0 0 0 0)
               (file-jpeg-save RUN-NONINTERACTIVE imgSkin layerSkin fullSkin fullSkin 0.97 0 TRUE FALSE "" 1 FALSE FALSE 2)
         )   )
         (gimp-image-delete imgSkin) ; clean-up the duplicated image
         (gimp-progress-set-text (string-append "KodiSave: " fullSkin))
         (gimp-message (string-append "KodiSave: " fullSkin))
)   )   )
(script-fu-register "script-fu-kodi-save" "_KodiSave" "KodiSave V1.5" "AlSchemist"
"2023, AlSchemist" "2023-04-28" "*"
SF-IMAGE      "image"         0
SF-DRAWABLE    "drawable"      0
SF-OPTION      "Art type"       (vector->list vKodiArtSuffix)
SF-ADJUSTMENT  "FanArt only" '(0     0     30    1        10       0      1)
;SF-ADJUSTMENT  "slider name" '(value lower upper step_inc page_inc digits type)
; SF-VALUE      "FanArt only"   "0"
)
(script-fu-menu-register "script-fu-kodi-save" "<Image>/File/Save/")

Attachment:
KodiSaveClearArt1.png
KodiSaveClearArt1.png [ 132.15 KiB | Viewed 1650 times ]

kittmaster wrote:
a bonus would be when the save/export is called, that all of the art types are represented with checkboxes defaulted to FALSE and when you select a single only checkmark, it uses that checkmarks index to output the appropriate file naming convention.

Checkboxes in Gimp Script-Fu are defined by SF-TOGGLE. However the user could check more than one art type.
I prefer a listbox more easier to be coded in only one line since the vector of art type already exists since version 1.0 :mrgreen:
SF-OPTION      "Art type"             (vector->list vKodiArtSuffix)

  1. In File Explorer, navigate in Movies\Aliens (1986)
    Drag & drop for example iconAlien.png in the Gimp empty editor.
    This icon has been generated by AI-based Bing Image Creator from a textual description then modified :paint in Gimp. :gimp
  2. Click menu KodiSave
  3. The Script-Fu:KodiSave dlgbox pop-ups. Click the listbox down arrow.
  4. Select your art type such as "clearart"
  5. Click OK
:vic
_____
Attachment:
KodiSaveClearArt2.png
KodiSaveClearArt2.png [ 142.26 KiB | Viewed 1650 times ]

Once you confirmed the saving of .xcf and the export to .png:
  1. A message is displayed in the Error Console as a Warning. :scram
    It is the only way that I know to display a persistent message.
  2. The Movies\Aliens (1986) folder is populated with the .xcf and .png :party
    Note that the basename includes the name of the movie.
  3. Close the current image with the shortcut Ctrl+W


Last edited by AlSchemist on Fri Apr 28, 2023 3:21 pm, edited 3 times in total.

Top
 Post subject: Next movie
PostPosted: Sun Apr 16, 2023 2:12 pm  (#15) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
Next movie
Attachment:
KodiSavePoster1.png
KodiSavePoster1.png [ 27.39 KiB | Viewed 1650 times ]

  1. In the File Explorer, go up to the parent folder: Movies
  2. Click the next movie
____________
art type = poster
Attachment:
KodiSavePoster2.png
KodiSavePoster2.png [ 138.01 KiB | Viewed 1650 times ]

  1. From the File Explorer, drag your media.
  2. And drop it on the Wilber icon in the Gimp Toolbox.
  3. Click menu KodiSave
  4. The Script-Fu:KodiSave dlgbox pop-ups. Click the listbox down arrow.
  5. Select another art type such as "poster"
  6. Click OK
____________
poster => .jpg
Attachment:
KodiSavePoster3.png
KodiSavePoster3.png [ 163.55 KiB | Viewed 1650 times ]

  1. The Kodi menu has been clicked in the previous step.
  2. A message is displayed in the Error Console as a Warning.
    Pay attention that for this art type, the file extension is .jpg instead of .png
  3. The Movies\Avatar (2009) folder is populated with the .xcf and .jpg

Note: saving a picture in .jpg destroys a little bit its quality at each saving. :hoh
(file-jpeg-save RUN-NONINTERACTIVE imgSkin layerSkin fullSkin fullSkin 0.97 0 TRUE FALSE "" 1 FALSE FALSE 2)

In the Script-Fu console if you click the Browse button for the function file-jpeg-save, you could read its help:
(file-jpeg-save run-mode image drawable filename raw-filename quality smoothing optimize progressive comment subsmp baseline restart dct)

quality = 0.97 More the quality is close to 100% more the .jpg is big.
Tune other parameters since I never save in .jpg format. I prefer the Google format Web Photo: .webp :yes

Once you saved .xcf and exported .png or .jpg according to the art type,
do you go to the next movie or you prefer to keep the current image in the Gimp editor for example to improve the .xcf
Give details how you switch between movies.

Do you wish to persist the shape of the last selection between two movies? :ninja
What kind of basic editing could be scripted? :cofscreen


Top
 Post subject: Re: Shortening mouse/keystrokes save/export script or method to implem
PostPosted: Sun Apr 16, 2023 9:10 pm  (#16) 
Offline
GimpChat Member

Joined: Dec 27, 2022
Posts: 22
I just gave it a whirl....very nice...easy to use.

I made some changes to the array image types, see code below.

I also moved the location to the file menu as that is where I would put it (I understand current location makes access easy)

For the FanartSharp, the # sign is actually used for a place holder to support multiple fanart images as there can be more than one. There is always fanart.jpg.... always, media companion (which I use) offers up to 10 additional.... so there should/could be up to 10 more images in the folder. So it would look like fanart1.jpg, fanart2.jpg, fanart3.jpg, fanart4.jpg......and so on.

So I think it would need a modification so if in the pulldown you select fanart for the output of the image, then it enables a spinner. If 0, then fanart.jpg, 1 fanart1.jpg, 2 fanart2.jpg......and so on.

Not sure how easy that is implemented, but that is how the naming was established via kodi. The link is working now:

https://kodi.wiki/view/Artwork_types#fanart#

https://kodi.wiki/images/7/7c/LocalTVShowArtwork01.jpg

When export is complete, switching to the next movie, I found myself closing all the files and starting a manual selection of the next movie.

Most of this is done in a sandbox before moving to a storage NAS because trying to do it live could cause errors and that would be a bad thing.

So once save/export is done, that is where it should stop. I will think about the workflow a bit more and update if it makes sense to modify or leave as is.

The only other thought would be, the "bar" that shows status...is there a way to have a text label that says something like "Save Status:" above it?

I was thinking having a message prior to saving "Waiting for User Selection"... after options are selected... then it updates as it does now.

If not, no issue, just thinking out loud.

Let me think about the basic editing inquiry, that requires a bit of A > B > C > D thinking before I can make a suggestion there.

Marvelous work!! :jumpclap :jumpclap

EDIT:

My modified code:
; script-fu-kodi-save.scm 1.2 saves the current image as .xcf and export as .png
; according to the art type option selected in the dialog box
; Copyright (C) 2023 AlSchemist. All Rights Reserved.
; Line: 148 define: 7 comment: 44 = 29.7% blank: 9
; The following is free TinyScheme open source copyrighted AlSchemist developed for Gimp 2.10.34

; Vector of Kodi art types
; Zero-based artType:     0       1      2        3              4          5           6         7        8             9
(define vKodiArtSuffix #("actor" "back" "banner" "characterart" "clearart" "clearlogo" "discart" "fanart" "fanartSharp" "keyart" "landscape" "poster" "spine" "thumb"))

; vector of overlay boolean by art type: #t means .png otherwise #f stands for .jpg

(define vOverlay       #(#f      #f     #f       #t             #t         #t          #t        #f       #f             #f      #f          #f       #f      #f))
; orig (define vOverlay       #(#t      #t     #t       #t             #t         #t          #t        #t       #t             #f      #f          #f       #t      #t))


; Display all art types defined in the vector vKodiArtSuffix
; (DisplayAllArtType)
; art type 0: actor 1: back 2: banner 3: characterart 4: clearart 5: clearlogo
; 6: discart 7: fanart 8: fanartSharp 9: keyart 10: landscape 11: poster 12: spine 13: thumb()
(define (DisplayAllArtType)
   (let*   (    (artTypeMax (vector-length vKodiArtSuffix))   ; index maximum in vKodiArtSuffix
         )
      (display "art type")
      (let loop ((idx 0)) ; starting 0-based index
         (if (< idx artTypeMax) ; Loop while the index does not reach the maximum
            (begin
               (if (= idx 6) (displayln "") (display " "))
               (display idx) (display ": ") (display (vector-ref vKodiArtSuffix idx))
               (loop (+ idx 1)) ; recursive call incrementing the index of art type
)   )   )   )   )

; Display all art types and the corresponding overlay predicate
; (DisplayOverlay)
; art type 0: actor no transparency as .jpg
; art type 1: back no transparency as .jpg
; art type 2: banner no transparency as .jpg
; art type 3: characterart transparent overlay as .png
; art type 4: clearart transparent overlay as .png
; art type 5: clearlogo transparent overlay as .png
; art type 6: discart transparent overlay as .png
; art type 7: fanart no transparency as .jpg
; art type 8: fanartSharp no transparency as .jpg
; art type 9: keyart no transparency as .jpg
; art type 10: landscape no transparency as .jpg
; art type 11: poster no transparency as .jpg
; art type 12: spine no transparency as .jpg
; art type 13: thumb no transparency as .jpg
; ()
(define (DisplayOverlay)
   (let*   (    (artTypeMax (vector-length vKodiArtSuffix))   ; index maximum in vKodiArtSuffix
            (overlayMax (vector-length vOverlay))
         )
      (if (<> artTypeMax overlayMax) (error "vKodiArtSuffix length does not match with vOverlay length"))
      (let loop ((idx 0)) ; starting 0-based index
         (if (< idx artTypeMax) ; Loop while the index does not reach the maximum
            (let*   (   (isPng?   (vector-ref vOverlay idx)))
               (display "art type ")
               (display idx) (display ": ") (display (vector-ref vKodiArtSuffix idx))
               (if isPng? (displayln " transparent overlay as .png") (displayln " no transparency as .jpg"))
               (loop (+ idx 1)) ; recursive call incrementing the index of art type
)   )   )   )   )

; Return the image id of the first currently loaded image
; (gimp-image-get-id)
; 1
(define (gimp-image-get-id)
   (let*   ((lstImg (gimp-image-list)))
      (if (zero? (car lstImg)) ; number of loaded image = 0?
         (error "3000. gimp-image-get-id: no image is open in Gimp.\nHow to fix it? Gimp menu \"File\" > \"Open\" > .webp or .png")
         (vector-ref (cadr lstImg) 0) ; the first loaded image
)   )   )

; Returns a vector composed by the path, the basename and the file extension of the image having img as id
; (PathInfoPic (gimp-image-get-id))
; #("C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng" "iconAlSchemist" "png")
(define (PathInfoPic img)
   (let*   (    (fullname (car (gimp-image-get-filename img)))
            (lstPath  (strbreakup fullname DIR-SEPARATOR)) ; split the fullname removing each DIR-SEPARATOR
            (lstDir   (reverse (cdr (reverse lstPath))))   ; remove the filename from lstPath
            (path     (unbreakupstr lstDir DIR-SEPARATOR)) ; Rebuild the path without the filename
            (filename (car (last lstPath))) ; filename is the last string of lstPath
            (lstFile  (strbreakup filename ".")) ; split the filename into the basename and the fileExt
            (basename (car lstFile))
            (filExt   (car (last lstFile))) ; without dot
         )
      (vector path basename filExt)
)   )

; Split path into drive, root and folder. path must not ends by DIR-SEPARATOR
; (PathSplit "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng")
; #("C:" "C:\\Tool\\Gimp\\forum\\GimpChat" "SaveXcf-ExportPng")
(define (PathSplit path)
   (let*   (    (lstPath  (strbreakup path DIR-SEPARATOR)) ; split the path removing each DIR-SEPARATOR
            (lstDir   (reverse (cdr (reverse lstPath))))   ; remove the last folder from lstPath
            (root     (unbreakupstr lstDir DIR-SEPARATOR)) ; Rebuild the root without the last folder
            (folder   (car (last lstPath))) ; folder is the last string of lstPath
            (drive    (car lstPath))
         )
      (vector drive root folder)
)   )

; Return the full path of the image with Kodi skin suffix according to the artType
; (KodiSkinPath "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng\\Movies\\Aliens (1986)" "Aliens (1986)" 4)
; "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng\\Movies\\Aliens (1986)\\Aliens (1986)-clearart.png"
; (KodiSkinPath "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng\\Movies\\Aliens (1986)" "Aliens (1986)" 10)
; "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng\\Movies\\Aliens (1986)\\Aliens (1986)-landscape.jpg"
(define (KodiSkinPath path basename artType)
   (let*   (    (isPng?   (vector-ref vOverlay artType))
            (filExt   (if isPng? ".png" ".jpg"))
            (filename (string-append basename "-" (vector-ref vKodiArtSuffix artType) filExt))
            (fullname (string-append path DIR-SEPARATOR filename))
         )
      fullname
)   )

; Click "KodiSave" after "Help" in the Gimp toolbar
(define (script-fu-kodi-save img layer artType)
   (let*   (    (vInfoPic (PathInfoPic img)) ; Split the full path of image in path, basename and extension
            (pathPic  (vector-ref vInfoPic 0)) ; 0-based element in the vector
            (vPath    (PathSplit pathPic)) ; Split the path in drive, root and folder
            (root     (vector-ref vPath 1))
            (folder   (vector-ref vPath 2))
            (fileXcf  (string-append folder ".xcf")) ; XCF has the folder as basename
            (fullXcf  (string-append pathPic DIR-SEPARATOR fileXcf))
            (fullSkin (KodiSkinPath pathPic folder artType))
            (isPng?   (vector-ref vOverlay artType))
            (imgSkin  (car (gimp-image-duplicate img))) ; Duplicate the current image
         )
      (gimp-xcf-save 0 img layer fullXcf fullXcf) ; Save the current image as XCF
      (let*   (   (imgXcf (car (gimp-file-load RUN-NONINTERACTIVE fullXcf fullXcf))) ; Reload XCF
            )
         (gimp-displays-reconnect img imgXcf)
         (gimp-image-clean-all imgXcf)
         (gimp-image-merge-visible-layers imgSkin CLIP-TO-IMAGE) ; Merge all layers before saving as PNG
         (let*   ((layerSkin (car (gimp-image-get-active-drawable imgSkin))))
            (if isPng?
               (file-png-save RUN-NONINTERACTIVE imgSkin layerSkin fullSkin fullSkin 0 9 0 0 0 0 0)
               (file-jpeg-save RUN-NONINTERACTIVE imgSkin layerSkin fullSkin fullSkin 0.97 0 TRUE FALSE "" 1 FALSE FALSE 2)
         )   )
         (gimp-image-delete imgSkin) ; clean-up the duplicated image
         (gimp-progress-set-text (string-append "KodiSave: " fullSkin))
         (gimp-message (string-append "KodiSave: " fullSkin))
)   )   )
(script-fu-register "script-fu-kodi-save" "KodiSave" "KodiSave V1.2" "AlSchemist"
"2023, AlSchemist" "2023-04-16" "*"
SF-IMAGE      "image"               0
SF-DRAWABLE    "drawable"            0
SF-OPTION      "Art Type"             (vector->list vKodiArtSuffix)
)
(script-fu-menu-register "script-fu-kodi-save" "<Image>/File/Save/")


Top
 Post subject: KodiSave 1.3 FanArt#
PostPosted: Thu Apr 20, 2023 3:21 pm  (#17) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
KodiSave 1.3 FanArt#

See above the updated source code 1.3. :mrgreen:

kittmaster wrote:
I also moved the location to the file menu as that is where I would put it

You are no longer a rookie :mcof if you are able to move a menu and patch the vector vOverlay of booleans, which is an abstract structure.
Great learning! :yesnod

kittmaster wrote:
the "bar" that shows status...is there a way to have a text label that says something like "Save Status:" above it?
...having a message prior to saving "Waiting for User Selection"... after options are selected...

It is too ambitious :huh for Gimp 2.10 and the :luvstruck old-fashioned :flirt Script-Fu. :geeking
There is not any event fired :runpup between the click to the menu "Kodi" and the click to "OK" button that runs:
(script-fu-kodi-save img layer artTypeIdx fanArtNbr)


kittmaster wrote:
enables a spinner. If 0, then fanart.jpg, 1 fanart1.jpg, 2 fanart2.jpg

SF-ADJUSTMENT  "FanArt only" '(0     0     30    1        10       0      0)
;SF-ADJUSTMENT  "slider name" '(value lower upper step_inc page_inc digits type)


Attachment:
KodiSaveFanArt0.png
KodiSaveFanArt0.png [ 125.94 KiB | Viewed 1621 times ]

By defaut the FanArt only numerical suffix is zero:

Attachment:
KodiSaveFanArt0saved.png
KodiSaveFanArt0saved.png [ 120.74 KiB | Viewed 1621 times ]

it is not added after "-fanart".

Attachment:
KodiSaveFanArt1.png
KodiSaveFanArt1.png [ 133.93 KiB | Viewed 1621 times ]

If the user clicks on the upper arrow of the spinner or moves the cursor, :idea:
FanArt only numerical suffix is added after "-fanart" and before the file extensionn ".jpg"

Finally, pay attention to the underscore :homer before the letter K of "KodiSave":
(script-fu-register "script-fu-kodi-save" "_KodiSave" "KodiSave V1.3" "AlSchemist"
...
)

It enables the shortcut Alt+File > KodiSave. :coolguy


Top
 Post subject: Re: Shortening mouse/keystrokes save/export script or method to implem
PostPosted: Sat Apr 22, 2023 7:51 am  (#18) 
Offline
GimpChat Member

Joined: Dec 27, 2022
Posts: 22
The revision is exactly what I was looking for it to do... :jumpclap :coolthup

I gave it some exercise, it did generate one unexpected result and I can't replicate it, but figure I post it so you can see what I ran into and if you may have an idea what might have caused it.

I took an image from my NAS collection. It was the landscape image of Aliens (1986). I renamed it to "Aliens Horizontal image.jpg" for the sake testing.

I created a folder on my desktop: Aliens (1986) ----> Just as it would be as expected from intent of this script.

The order I tried before I noticed the issue:

--- I loaded the image in GIMP
--- Exported Landscape -> OK
--- Exported Actor -> OK
--- Exported Fanart - Spinner set to 6 -> Failed, added suffix unexpectedly as fanart5.XXXXXXX -> continue
--- Exported Fanart - Spinner set to 5 -> OK
--- Exported Fanart - Spinner set to 6 -> OK

Deleted all images except starting image "Aliens Horizontal image.jpg"

Replicated steps above, no issue all exported OK.

Not sure how to replicate this issue, only happened once thus far, so I'll try to track it, but figured I'd provide feedback incase you may have an idea what generated the issue.

It seems like an initialization variable may be needed set to 0?

I was going to take a look to see if I can manage that, but not sure as of this writing.

Other than that, this thing is excellent and amazed with the outcome, thank you again for the efforts, reading the code helps me a bit more to understand how scheme works. Never used this language before, so it is a good learning experience.

:paint :clap

Chris


Attachments:
File comment: Initial File for testing
Screenshot 2023-04-22 082821.png
Screenshot 2023-04-22 082821.png [ 9.27 KiB | Viewed 1597 times ]
File comment: Results from the explanation from above
Screenshot 2023-04-22 082655.png
Screenshot 2023-04-22 082655.png [ 29.63 KiB | Viewed 1597 times ]
Top
 Post subject: Re: Shortening mouse/keystrokes save/export script or method to implem
PostPosted: Sat Apr 22, 2023 8:11 am  (#19) 
Offline
GimpChat Member

Joined: Dec 27, 2022
Posts: 22
Also forgot to mention, it seems to be warning me every time it exports even though it works as expected. I did a normal export and it didn't flag any warnings.

Have no idea what would cause that, but noticed the behavior.


Attachments:
File comment: Warnings: Not sure why, but still works correctly...odd
Screenshot 2023-04-22 090712-edit.png
Screenshot 2023-04-22 090712-edit.png [ 783.15 KiB | Viewed 1596 times ]
Top
 Post subject: KodiSave 1.4 FanArt# as integer
PostPosted: Sun Apr 23, 2023 9:45 am  (#20) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
KodiSave 1.4 FanArt# as integer

See above the updated source code 1.4. :mrgreen:

kittmaster wrote:
be warning me every time it exports even though it works as expected

This behavior is by design. Since, the KodiSave message in the status bar could disappear,
we use the Error window to persist the message as a warning even if it is not a warning or an error.

If you do not wish any message in the Error window, put in comment adding ";" in the beginning of the line 154:
(gimp-message (string-append "KodiSave: " fullSkin))

Alternatively, if you do not wish to put in comment gimp-message, you can delete this line.

kittmaster wrote:
Exported Fanart - Spinner set to 6 -> Failed, added suffix unexpectedly as fanart5.XXXXXXX

Do you remember if you moved the cursor or clicked to upper arrow of the spinner?
For unknown reason :crash , the FanArt only index was incremented from 5 to the float number 5.7073 :sword
To fix the issue:
  1. We removed the cursor keeping only the spinner: type = 1 instead of 0 in the last parameter.
    SF-ADJUSTMENT  "FanArt only" '(0     0     30    1        10       0      1)

  2. The procedure (define (KodiSkinPath path basename artTypeIdx fanArtNbr) has been improved to convert fanArtNbr from float to integer in case where the spinner would return a float number. Normally, the spinner should not return a float since the step is the integer 1 without any decimal dot.

How to convert a float to an integer in Script-Fu?
You can copy and paste the following code in the Script-Fu console.

(trunc (round 5.7073))

6

The boundary is at the half of the interval between 5.0 and 6.0: 5.5
(trunc (round 5.5))

6

(trunc (round 5.4))

5

Into the bargain, if there is a decimal dot in the conversion from number to string, we split the string with the known function strbreakup used to split a filename into a root and a file extension:
(car (strbreakup (number->string 5.7073 10) "."))

"5"

You can try without the function car to get the list of the numbers before and after the decimal dot:
(strbreakup (number->string 5.7073 10) ".")

("5" "7073")

Finally, if the issue occurs too often, put in comment adding ";" in the beginning of the line "SF-ADJUSTMENT".
Then remove ";" in the line below starting with "SF-VALUE". The spinner will be replaced with an input box initialized with "0".

Before: with the spinner
SF-ADJUSTMENT  "FanArt only" '(0     0     30    1        10       0      1)
;SF-ADJUSTMENT  "slider name" '(value lower upper step_inc page_inc digits type)
; SF-VALUE      "FanArt only"   "0"


After: without the spinner but a basic input box
; SF-ADJUSTMENT  "FanArt only" '(0     0     30    1        10       0      1)
;SF-ADJUSTMENT  "slider name" '(value lower upper step_inc page_inc digits type)
SF-VALUE      "FanArt only"   "0"

In the free editor NotePad++, adding ";" in the beginning of the line renders the line as a green comment. :abduct

After the editing of a Script-Fu source code .scm such as KodiSave.scm, we recommend to close Gimp then restart Gimp even if there is the menu "Filter" > "Script-Fu" > "Refresh scripts".
So we are sure that the memory used by Script-Fu will be correctly released. :sglasses


Top
 Post subject: Re: Shortening mouse/keystrokes save/export script or method to implem
PostPosted: Tue Apr 25, 2023 9:49 am  (#21) 
Offline
GimpChat Member

Joined: Dec 27, 2022
Posts: 22
I was trying 1.4 out but not for fanart (other things to complete), I went to export as banner and ran into this output error:


Attachments:
File comment: Save as banner operation
Screenshot 2023-04-25 104744.png
Screenshot 2023-04-25 104744.png [ 88.36 KiB | Viewed 639 times ]
Top
 Post subject: Re: Shortening mouse/keystrokes save/export script or method to implem
PostPosted: Wed Apr 26, 2023 2:30 pm  (#22) 
Offline
GimpChat Member

Joined: Dec 27, 2022
Posts: 22
Also, can you guide me to a scheme debugger so I can single step and try and learn the code sequence?

I found DrRacket, but it was not working as I expect with GIMP script. I do use Visual Studio for C++ and VB, so it isn't a stretch to learn, just knowing the right tool and getting it setup so I can learn and adapt to a different environment.

Thanks again for all your help, will continue to try and understand how scheme works.

Chris


Top
 Post subject: Error: car: argument 1 must be: pair
PostPosted: Wed Apr 26, 2023 5:24 pm  (#23) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
I cannot reproduce the following issue with art type "Banner" index 2 in KodiSave 1.4
Try to indicate more context such as full path of picture, states of each element of the KodiSave dialog box.

Error: car: argument 1 must be: pair

Run the Script-Fu console by "Filters" > "Script-Fu" > "Console" (Alt+R S C).

The function car retrieves the first element of a given list such as '("root" "png")
(car '("root" "png"))

"root"

Let us remove manually the first element. The list becomes '("png")
(car '("png"))

"png"

Let us remove again the first element. The list becomes empty '()
(car '())

Error: car: argument 1 must be: pair :gaah
In other words, car does not like the empty list.

In KodiSave 1.4, I mainly introduced car in KodiSkinPath in the affection of the local variable strFanArt of type string.
(strFanArt   (car (strbreakup (number->string intFanArt 10) ".")))

You cannot directly run this affection.
But try to run the examples in comment starting with ";" above the define such as the last one:

Do not copy the ";" but after from the opening parenthesis until the corresponding closing parenthesis.
(KodiSkinPath "C:\\Movies\\Aliens (1986)" "Aliens (1986)" 7 5.1)

"C:\\Movies\\Aliens (1986)\\Aliens (1986)-fanart5.jpg"
It does not matter if the path exists or not.
The expected result is also supplied as a comment before the define.

Try to reproduce your own context about:
  • your path of picture. Do not forget to double backslash in Windows;
  • your art type banner has for index 2 instead of fanart at 7;
  • fanArtNbr should be 0 but indicate the real number of the spinner.


Last edited by AlSchemist on Wed Apr 26, 2023 5:41 pm, edited 1 time in total.

Top
 Post subject: Debugging Script-Fu
PostPosted: Wed Apr 26, 2023 5:31 pm  (#24) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
Debugging Script-Fu

You can debug only in the Script-Fu console.
Close Gimp then restart it
You must reproduce the parameters during the call of (script-fu-kodi-save img layer artTypeIdx fanArtNbr)
  • img should be 1 if it is the first picture in Gimp. To confirm, run: (gimp-image-get-id)
  • layer, run: (car (gimp-image-get-active-drawable 1)) ; if img is 1, the layer could be 2 ;
    Alternatively, try: (car (gimp-image-get-active-drawable (gimp-image-get-id)))
  • artTypeIdx: for banner, indicate the index 2
  • fanArtNbr: should be 0

So clicking to the menu File > KodiSave is equivalent to the call in the console:
(script-fu-kodi-save 1 2 2 0)

(#t)

If you do not want to manage the first two parameters,
replace img and layer by the call of their respective functions, but it is longer:
(script-fu-kodi-save (gimp-image-get-id) (car (gimp-image-get-active-drawable (gimp-image-get-id))) 2 0)

(#t)

In the console, you can enable tracing for debugging purpose by:
(tracing 1)

"Gives: 0" should be the Script-Fu's answer displaying the previous state of tracing.

tracing will trace all calls until the fatal error.

Disable the tracing by:
(tracing 0)

Eval: (tracing 0)
Eval: tracing
Eval: 0
Apply to: (0)1

Tracing is extremely verbose: 4 instructions are displayed to disable the tracing.
You could insert (tracing 1) inside any function to start tracing only on purpose.
But choose the function that could be the closest of the bug.
Otherwise, you could have a lot of traces and the performance is dramatically reduced.

When you call a function in the console, you can use:
(display "text")

text#t

and
(displayln "return to the line")

return to the line
#t

display could be more useful than:
(gimp-message "warning")

gimp-message displays a warning in the Error window.

Finally, try to run all the calls in comment and compare with each expected result.
Search the functions that call car.

You can remove the body of let* to check only if the local variables work. :hi5
See in post #6 "let* us introduce local variables:".

If all local variables work, reintroduce step by step the body of let* until the fatal error is found.


Last edited by AlSchemist on Fri Apr 28, 2023 12:20 pm, edited 2 times in total.

Top
 Post subject: Environment of developement for Script-Fu
PostPosted: Wed Apr 26, 2023 5:40 pm  (#25) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
Environment of developement for Script-Fu

DrRacket is the best to learn the different dialects about Scheme.
However starting DrRacket is very long.
You cannot simulate the Gimp API: so all functions beginning with "gimp-" do not work.

Try DrRacket to learn the basic primitives of Scheme. DrRacket has a classical debugger
If you select for example "let*" then press F1, there is a contextual help online

Visual Studio or VScode could edit .scm source file: search "scheme" in the free extensions to color the keywords.

I prefer Notepad++ menu "Language" > "Scheme" because the loading of the editor is faster.
Ctrl+Alt+B on the closing parenthesis selects the entire Scheme expression until the corresponding open parenthesis.
It is very useful to copy and paste a call to a function and its parameters in the console.

In all cases, only the Script-Fu console must be used to run Script-Fu source code .scm

Running remotely Gimp as a Script-Fu server from the client NotePad++ or VScode is out of the scope of this post.
Gimp menu "Filter" > "Script-Fu" > "Start Server..." :ninja


Top
 Post subject: Re: Error: car: argument 1 must be: pair
PostPosted: Thu Apr 27, 2023 8:34 pm  (#26) 
Offline
GimpChat Member

Joined: Dec 27, 2022
Posts: 22
AlSchemist wrote:
I cannot reproduce the following issue with art type "Banner" index 2 in KodiSave 1.4
Try to indicate more context such as full path of picture, states of each element of the KodiSave dialog box.

Error: car: argument 1 must be: pair

Run the Script-Fu console by "Filters" > "Script-Fu" > "Console" (Alt+R S C).

The function car retrieves the first element of a given list such as '("root" "png")
(car '("root" "png"))

"root"

Let us remove manually the first element. The list becomes '("png")
(car '("png"))

"png"

Let us remove again the first element. The list becomes empty '()
(car '())

Error: car: argument 1 must be: pair :gaah
In other words, car does not like the empty list.

In KodiSave 1.4, I mainly introduced car in KodiSkinPath in the affection of the local variable strFanArt of type string.
(strFanArt   (car (strbreakup (number->string intFanArt 10) ".")))

You cannot directly run this affection.
But try to run the examples in comment starting with ";" above the define such as the last one:

Do not copy the ";" but after from the opening parenthesis until the corresponding closing parenthesis.
(KodiSkinPath "C:\\Movies\\Aliens (1986)" "Aliens (1986)" 7 5.1)

"C:\\Movies\\Aliens (1986)\\Aliens (1986)-fanart5.jpg"
It does not matter if the path exists or not.
The expected result is also supplied as a comment before the define.

Try to reproduce your own context about:
  • your path of picture. Do not forget to double backslash in Windows;
  • your art type banner has for index 2 instead of fanart at 7;
  • fanArtNbr should be 0 but indicate the real number of the spinner.


I have found the reason but not sure the fix.

I open gimp, images located in "C:\Users\chris\Desktop\Kodi\1883 (2023)", load image file 1, load image file 2, merge 1 and 2 into template (banner > local template to me 1000x185)... click on KodiSave... "Error: car: argument 1 must be: pair"

Now, if I do a File > Save As > Whatever.xcf

Return and Click "KodiSave".... select banner > works as it did before......all good.

So something strange with the initial save aspect??

I am using your info about debugging in console to trace, some things I can see/understand, many of the things I try I get:

> PathInfoPic
#<CLOSURE>


Top
 Post subject: Re: Shortening mouse/keystrokes save/export script or method to implem
PostPosted: Thu Apr 27, 2023 8:59 pm  (#27) 
Offline
GimpChat Member

Joined: Dec 27, 2022
Posts: 22
I got how to reproduce error, using method I described above.

It works with a single layer, 2 layers, 3 layers > crash (I assume it will also crash on 5, 7, 9, 11 or any other odd number of layers)

Ok, so I open image 1 (Tab1)
Open image 2 (Tab 2)
Create new image (Tab 3 Blank > Dimensions I am using 1000x185 > Should not matter)

Tab 1, select all, Copy, Paste as new layer into Tab 3
Tab 2, select all, Copy, Paste as new layer into Tab 3

Kodisave with Tab 3 Active > Click > must be: Pair error

I have to do the method this way because in order to create a "banner" for Kodi, I need a Main background image of the movie/tv show itself, I use the "clearlogo.png" of the movie/tv show, those two items are combined in Tab 3 using predefined template dimensions of 1000x185 pixel requirements set by Kodi and I use for all banner creation so I don't have to think about it and reduces setup and keystroke entries etc.

So it seems the script is trying to do something in pairs vs the active tab layer when it is active.

I "think" that is were the issue is, but I can't seem to follow the scheme code to try and adjust it. I will continue to look at it.

As a note, 1.2 didn't have this issue. 1.3 is missing in this thread as it was over written by 1.4. So I can't verify 1.3, I am looking to see if I saved a backup copy somewhere so I can test that to see where the issue come in.

Hopefully this helps give some insight??

Best,
Chris


Top
 Post subject: KodiSave 1.5 untitled image
PostPosted: Fri Apr 28, 2023 3:44 pm  (#28) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
Great description, Chris! :bigthup

:drum KodiSave 1.5 untitled image :drum

See in page 2 the updated source code 1.5. :mrgreen:

kittmaster wrote:
images located in "C:\Users\chris\Desktop\Kodi\1883 (2023)", load image file 1, load image file 2, merge 1 and 2 into template (banner

So merge 1 and 2 should be in the same folder than the last loaded image 2.

kittmaster wrote:
Create new image

This the new operating mode.
In all previous screen captures in page 1-2, the first step was a drag-and-drop: so the target picture had always a title.

When you create a new picture, the image has not yet been saved and its title is: "Untitled":

Attachment:
Untitled.png
Untitled.png [ 139.58 KiB | Viewed 611 times ]


KodiSave 1.5 introduces the new function SearchFilename starting from the target image having merge 1 and 2.
If the filename is empty, SearchFilename searchs in the vector of all loaded images then choose the last loaded image having a non empty filename.

Attachment:
Banner.png
Banner.png [ 164.44 KiB | Viewed 611 times ]

In our case, it is picture 2 with a green frame.

The SearchFilename code begins to be complex with three levels of let* :shock: including a loop in the vector of image id.


Top
 Post subject: How to debug the car issue?
PostPosted: Fri Apr 28, 2023 3:54 pm  (#29) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
How to debug the car issue?

(tracing 1)

enabled the very very long trace of all functions ended by (car '()) ; first element of the empty list generated the fatal error.

After the error, never forget to restore the disabled trace by:
(tracing 0)


The bug was in PathInfoPic: the fullname of an untitled image was the empty string. :oops:
Spliting the empty fullname removing each DIR-SEPARATOR generated ("").
Removing the filename from lstPath generated the empty list ().
Rebuilding the path without the filename caused the fatal error in unbreakupstr. :roll:
This function is provided in C:\Program Files\GIMP 2\share\gimp\2.0\scripts\script-fu-compat.init
And, until now, I did not know that unbreakupstr could include the call of car.

The fun of the story is that, in 1.5, I instrumented KodiSave replacing all calls of car by a debug version named carDbg.
carDbg does exactly what car does but if the list is empty, carDbg displays the running context: the caller and one of its parameter.
In fact, carDbg never fired the fatal error since it was in :shoot unbreakupstr :arrowshoot outside KodiSave.


Last edited by AlSchemist on Fri Apr 28, 2023 4:17 pm, edited 1 time in total.

Top
 Post subject: Welcome to Lisp
PostPosted: Fri Apr 28, 2023 4:02 pm  (#30) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
Welcome to Lisp

kittmaster wrote:
PathInfoPic

#<CLOSURE>

The notion of closure is relative to an environment and the scope of variables.
Is the function PathInfoPic a closure? :geek:
(closure? PathInfoPic)

#t

Is the function PathInfoPic a procedure? :yesnod
(procedure? PathInfoPic)

#t

Retrieving the Lisp code of a closure as lambda expression:
(get-closure-code PathInfoPic)

(lambda (img) (let* ((fullname (SearchFilename img)) (lstPath (strbreakup fullname DIR-SEPARATOR)) (lstDir (reverse (cdr (reverse lstPath)))) (path (unbreakupstr lstDir DIR-SEPARATOR)) (filename (carDbg (last lstPath) 'PathInfoPic2 lstPath)) (lstFile (strbreakup filename ".")) (basename (carDbg lstFile 'PathInfoPic3 filename)) (filExt (carDbg (last lstFile) 'PathInfoPic4 filename))) (vector path basename filExt)))

Is the function car a procedure?
(procedure? car)

#t

However car is not a closure: :geeking
(closure? car)

#f

One cannot retrieve the Lisp code of car since it is a basic primitive. ;)
(get-closure-code car)

#f


Top
Post new topic Reply to topic  [ 42 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 5 hours [ DST ]


   Similar Topics   Replies 
No new posts Attachment(s) CanNot Move object (Mouse Action Blocked) via mouse cursor Rotate Icon

6

No new posts Attachment(s) Batch export all opened images script for GIMP [Update]

13

No new posts CMYK student is going to implement non-destructive filters soon

0

No new posts Where did GIMP save my file, & how do I change default save location

5

No new posts Attachment(s) A New 3D Text Method

7



* Login  



Powered by phpBB3 © phpBB Group