Sun Mar 19, 2023 7:14 am
Thu Apr 06, 2023 3:54 pm
C:\Users\YourWindowsUserName\AppData\Roaming\GIMP\2.10\scripts
Fri Apr 07, 2023 6:55 am
Fri Apr 07, 2023 6:57 am
Fri Apr 07, 2023 11:25 am
(gimp-version)
(gimp-image-list)
(define img 1)
img
(gimp-image-get-filename img)
(car (gimp-image-get-filename img))
(define fullname (car (gimp-image-get-filename img)))
fullname
Fri Apr 07, 2023 11:40 am
(strbreakup fullname DIR-SEPARATOR)
(define filename (car (last (strbreakup fullname DIR-SEPARATOR))))
filename
(define basename (car (strbreakup filename ".")))
basename
(define filePng (string-append basename "-clearart.png"))
filePng
(let* ( (fullname (car (gimp-image-get-filename img)))
(filename (car (last (strbreakup fullname DIR-SEPARATOR))))
(basename (car (strbreakup filename ".")))
(filePng (string-append basename "-clearart.png"))
)
filePng
)
(let* ( (fullname (car (gimp-image-get-filename img)))
(lstPath (strbreakup fullname DIR-SEPARATOR))
(lstDir (reverse (cdr (reverse lstPath))))
(path (unbreakupstr lstDir DIR-SEPARATOR))
(filename (car (last lstPath)))
(basename (car (strbreakup filename ".")))
(filePng (string-append basename "-clearart.png"))
(fullpng (string-append path DIR-SEPARATOR filePng))
)
fullpng
)
(reverse (list "C:" "Tool" "Gimp" "forum" "GimpChat" "iconAlSchemist.png"))
(cdr (reverse (list "C:" "Tool" "Gimp" "forum" "GimpChat" "iconAlSchemist.png")))
(reverse (cdr (reverse (list "C:" "Tool" "Gimp" "forum" "GimpChat" "iconAlSchemist.png"))))
(drop-right (list "C:" "Tool" "Gimp" "forum" "GimpChat" "iconAlSchemist.png") 1)
Sat Apr 08, 2023 7:28 am
(define vKodiArtSuffix #("actor" "back" "banner" "characterart" "clearart" "clearlogo" "discart" "fanart" "fanartSharp" "keyart" "landscape" "poster" "spine" "thumb"))
(vector-ref vKodiArtSuffix 4)
(gimp-image-list)
(define (DisplayAllArtType)
(let* ( (artTypeMax (vector-length vKodiArtSuffix))
)
(displayln "")
(let loop ((idx 0)) ; starting 0-based index
(if (< idx artTypeMax) ; Loop while the index does not reach the maximum
(begin
(display "art type ") (display idx) (display ": ")
(displayln (vector-ref vKodiArtSuffix idx))
(loop (+ idx 1)) ; recursive call incrementing the index of art type
) ) ) ) )
(DisplayAllArtType)
(define (PathInfoPic img)
(let* ( (fullname (car (gimp-image-get-filename img)))
(lstPath (strbreakup fullname DIR-SEPARATOR))
(lstDir (reverse (cdr (reverse lstPath))))
(path (unbreakupstr lstDir DIR-SEPARATOR))
(filename (car (last lstPath)))
(lstFile (strbreakup filename "."))
(basename (car lstFile))
(filExt (car (last lstFile))) ; without dot
)
(vector path basename filExt)
) )
(PathInfoPic 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
) ) )
(gimp-image-get-id)
(define (KodiSkinPath img artType)
(let* ( (vInfoPic (PathInfoPic img))
(path (vector-ref vInfoPic 0)) ; 0-based element in the vector
(basename (vector-ref vInfoPic 1)) ; next element. We dont use filExt forcing ".png"
(filename (string-append basename "-" (vector-ref vKodiArtSuffix artType) ".png"))
(fullname (string-append path DIR-SEPARATOR filename))
)
fullname
) )
(KodiSkinPath (gimp-image-get-id) 4)
(KodiSkinPath (gimp-image-get-id) 12)
Sat Apr 08, 2023 11:33 am
Sat Apr 15, 2023 5:18 pm
; script-fu-kodi-save.scm 1.1 saves the current image as .xcf and export as .png
; according to the current art type saved in C:\Users\YourUserName\AppData\Roaming\GIMP\2.10\scripts\KodiSaveArtType.txt
; Copyright (C) 2023 AlSchemist. All Rights Reserved.
; Line: 184 define: 12 comment: 55 = 29.8% blank: 12
; The following is free TinyScheme open source copyrighted AlSchemist
; Write Windows EOL CR+LF in the file open as portOut
(define (writeCrLf portOut)
(write-char #\return portOut) ; Windows "\r" carriage-return
(newline portOut) ; Unix "\n" line feed
)
; Create the text file C:\\Users\\YourUserName\\AppData\\Roaming\\GIMP\\2.10\\scripts\\KodiSaveArtType.txt with index "4"
; (WriteKodiSaveArtType)
; #t
(define (WriteKodiSaveArtType)
(let* ( (filename "KodiSaveArtType.txt")
(fullname (string-append gimp-directory DIR-SEPARATOR "scripts" DIR-SEPARATOR filename))
)
(call-with-output-file fullname
(lambda (portOut)
(write 4 portOut)
(writeCrLf portOut)
) )
(file-exists? fullname) ; return #t if the generated file exists otherwise #f
) )
; Return the index 4 as integer read as string in C:\\Users\\YourUserName\\AppData\\Roaming\\GIMP\\2.10\\scripts\\KodiSaveArtType.txt
; In the vector vKodiArtSuffix, the zero-based index 4 corresponds to "clearart"
; (ReadKodiSaveArtType)
; 4
(define (ReadKodiSaveArtType)
(let* ( (filename "KodiSaveArtType.txt")
(fullname (string-append gimp-directory DIR-SEPARATOR "scripts" DIR-SEPARATOR filename))
)
(call-with-input-file fullname
(lambda (port)
(define strLine (read-line port))
(if (eof-object? strLine) 4 (string->number strLine 10))
) ) ) )
; 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"))
; Display the name of the cuurent ArtType read in text file KodiSaveArtType.txt
; (CurrentArtType)
; "clearart"
(define (CurrentArtType)
(let* ( (artTypeMax (vector-length vKodiArtSuffix)) ; index maximum in vKodiArtSuffix
(artType (ReadKodiSaveArtType))
)
(if (< artType 0) (error "artType should be equal or superior to 0"))
(if (>= artType artTypeMax) (error "artType should be inferior to" artTypeMax))
(vector-ref vKodiArtSuffix artType)
) )
; 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
) ) ) ) )
; 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)
) )
; Return the full path of the image having the id img with Kodi suffix according to the artType
; (KodiSkinPath (gimp-image-get-id) (ReadKodiSaveArtType))
; "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng\\iconAlSchemist-clearart.png"
(define (KodiSkinPath img artType)
(let* ( (vInfoPic (PathInfoPic img))
(path (vector-ref vInfoPic 0)) ; 0-based element in the vector
(basename (vector-ref vInfoPic 1)) ; next element. We dont use filExt forcing ".png"
(filename (string-append basename "-" (vector-ref vKodiArtSuffix artType) ".png"))
(fullname (string-append path DIR-SEPARATOR filename))
)
fullname
) )
; Click "KodiSave" after "Help" in the Gimp toolbar
(define (script-fu-kodi-save img layer)
(let* ( (vInfoPic (PathInfoPic img))
(path (vector-ref vInfoPic 0)) ; 0-based element in the vector
(basename (vector-ref vInfoPic 1)) ; next element. We dont use filExt forcing ".png"
(fileXcf (string-append basename ".xcf"))
(fullXcf (string-append path DIR-SEPARATOR fileXcf))
(artType (ReadKodiSaveArtType))
(fullPng (KodiSkinPath img artType))
(imgPng (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 imgPng CLIP-TO-IMAGE) ; Merge all layers before saving as PNG
(file-png-save RUN-NONINTERACTIVE imgPng (car (gimp-image-get-active-drawable imgPng)) fullPng fullPng 0 9 0 0 0 0 0)
(gimp-image-delete imgPng) ; clean-up the duplicated image
(gimp-progress-set-text (string-append "KodiSave: " fullPng))
(gimp-message (string-append "KodiSave: " fullPng))
) ) )
(script-fu-register "script-fu-kodi-save" "KodiSave" "KodiSave V1.1" "AlSchemist"
"2023, AlSchemist" "2023-04-16" "*"
SF-IMAGE "image" 0
SF-DRAWABLE "drawable" 0
)
(script-fu-menu-register "script-fu-kodi-save" "<Image>/")
;_______________________________ Section I/O begin by Richard O'Keefe
; https://legacy.cs.indiana.edu/scheme-repository/code.string.html
; Richard O'Keefe's generic read-string routine to port code to Scheme implementations
; that do not support a read-string or read-line primitive (readstring.oak).
; Original file: "readstring.oak" (c) Richard O'Keefe
; Get the text file via portin until #\newline
; Return (proc->string listOfChars) otherwise #<EOF>. Filter #\return #\newline
(define (read-chars-aux portin proc)
(let loop ((lstResult nil))
(let* ((ch (read-char portin)))
(if (eof-object? ch)
(if (pair? lstResult) (proc (reverse lstResult)) ch) ; EOF
(case ch ; optimised by AlSchemist 2021
((#\newline) (proc (reverse lstResult))) ; EOL
((#\return) (loop lstResult)) ; skip CR
(else (loop (cons ch lstResult)))
) ) ) ) )
;;; (read-chars [input-port])
;;; is just like read-string, except that it returns its result as a
;;; list of character codes. It exists for two reasons:
;;; (1) the portable implementation of read-string/read-line was
;;; already building such a list internally;
;;; (2) the operation is useful in its own right.
(define (read-chars . portin)
(read-chars-aux
(if (pair? portin) (car portin) (current-input-port))
(lambda (chars) chars)
) )
;;; Many Scheme systems provide a function called (read-string [input-port]) or
;;; (read-line [input-port])
;;; which reads a line of text (terminated by a #\Newline) from the given port
;;; (which defaults to the current input port, like all other Scheme input commands)
;;; and returns it as a string.
;;; If the end of the port is reached before a #\Newline has been read,
;;; an end of file object is returned
;;; (however many characters may have been read before the end of port was reached).
;;; This file was written to help me port programs between several dialects of Scheme,
;;; and uses no operations or constants that are not defined in the standard.
(define (read-line . portin)
(read-chars-aux (if (pair? portin) (car portin) (current-input-port)) list->string)
)
(define read-string read-line)
(WriteKodiSaveArtType)
(KodiSkinPath (gimp-image-get-id) (ReadKodiSaveArtType))
(ReadKodiSaveArtType)
(CurrentArtType)
(CurrentArtType)
Sat Apr 15, 2023 7:24 pm
AlSchemist wrote:Tell us how are organized the 250 items in term of folders and naming convention?
Are there consecutive in a given folder or in a tree of folders?
Why some items are in .jpg and other in .png format?
Sat Apr 15, 2023 9:27 pm
Sat Apr 15, 2023 10:05 pm
Sun Apr 16, 2023 6:11 am
kittmaster wrote:Error: eval: unbound variable: read-line
Sun Apr 16, 2023 1:54 pm
; 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/")
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.
SF-OPTION "Art type" (vector->list vKodiArtSuffix)
Sun Apr 16, 2023 2:12 pm
(file-jpeg-save RUN-NONINTERACTIVE imgSkin layerSkin fullSkin fullSkin 0.97 0 TRUE FALSE "" 1 FALSE FALSE 2)
(file-jpeg-save run-mode image drawable filename raw-filename quality smoothing optimize progressive comment subsmp baseline restart dct)
Sun Apr 16, 2023 9:10 pm
; 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/")
Thu Apr 20, 2023 3:21 pm
kittmaster wrote:I also moved the location to the file menu as that is where I would put it
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...
(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)
(script-fu-register "script-fu-kodi-save" "_KodiSave" "KodiSave V1.3" "AlSchemist"
...
)
Sat Apr 22, 2023 7:51 am
Sat Apr 22, 2023 8:11 am
Sun Apr 23, 2023 9:45 am
kittmaster wrote:be warning me every time it exports even though it works as expected
(gimp-message (string-append "KodiSave: " fullSkin))
kittmaster wrote:Exported Fanart - Spinner set to 6 -> Failed, added suffix unexpectedly as fanart5.XXXXXXX
SF-ADJUSTMENT "FanArt only" '(0 0 30 1 10 0 1)
(trunc (round 5.7073))
(trunc (round 5.5))
(trunc (round 5.4))
(car (strbreakup (number->string 5.7073 10) "."))
(strbreakup (number->string 5.7073 10) ".")
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"
; 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"