It is currently Thu Jun 27, 2024 7:07 pm


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: Shortening mouse/keystrokes save/export script or method to implement?
PostPosted: Sun Mar 19, 2023 7:14 am  (#1) 
Offline
GimpChat Member

Joined: Dec 27, 2022
Posts: 22
GIMP Version: 2.10.34
Operating System: Windows
GIMP Experience: Intermediate Level

List any relevant plug-ins or scripts:
Many, but doesn't affect my inquiry

List any ERROR messages you received:
None



I am looking for a solution that can help me simplify creating media after i save an .xcf file.

I'm am doing "clearart" for my Media center files that use Kodi. It is a multi step process but the most tedious is exporting.

Is there a script or method that will allow for:

- When I save as file.xcf
- Invoke > File > Export As > file-clearart.png (Simultaneously....in the same folder file.xcf > automatic overwrite without warning)

I am 100% aware about accidental overwrites, but since the export is the caboose of the process...I don't care....and I have backups of all the old if it were a problem....and it is a function of....if I save it as the file.xcf then I want the .png of that save regardless.

Is there a way to make this behavior occur? I don't personally write scripts and I don't have the bandwidth to learn it now, eventually I will.

I have over 250 items to get through and it is going to take time. So I'm trying to minimize any keystrokes/mouse movements. I've allocated a lot of keyboard shortcuts for the creation method...but I can't seem to find a way to simultaneously save and export.

Is there a script already out there or a way to do this?

Thank you,
Chris


Share on Facebook Share on Twitter Share on Orkut Share on Digg Share on MySpace Share on Delicious Share on Technorati
Top
 Post subject: Save .xcf and export .png
PostPosted: Thu Apr 06, 2023 3:54 pm  (#2) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
Save .xcf and export .png

With this shorter title, you would have an answer earlier
since "Shortening mouse/keystrokes" does NOT affect your basic inquiry.

save_and_export.scm by Rob should solve the issue. :yes

There are two functions that will appear in the first menu "File":
  1. save-as-and-export
  2. save-and-export
when you will copy the Rob's script save_and_export.scm in your:
C:\Users\YourWindowsUserName\AppData\Roaming\GIMP\2.10\scripts

Replace "YourWindowsUserName" with your real UserName in Windows to find the real path.

Then restarts Gimp.
The new menus "Save XCF and export..." and "Save-As XCF and export..." are grayed by default
until you open a picture from your 250 items used by Kodi.
One will never know what is the file extension of these items. :roll:

The first function save-as-and-export should be used the first time to save as .xcf and export as .png.
The dialog box asks you the folder and the filename.
Check the option [x] Export a png and eventually uncheck the option [ ] Export a jpg.

The second function save-and-export is simpler since there are only the two checkboxes png or/and jpg.
This means that the picture has already been saved, that is to say the picture has a name.
The Rob's script saves .xcf and .png with the same basename in the same folder. :geek


Top
 Post subject: Re: Shortening mouse/keystrokes save/export script or method to implem
PostPosted: Fri Apr 07, 2023 6:55 am  (#3) 
Offline
GimpChat Member

Joined: Dec 27, 2022
Posts: 22
Downloaded and used, does a good job, may tweak it for my application, but certainly saves some time. I'm already down to about 20 or so left, but will be helpful for future events.

The file extensions are nothing more than .jpg and .png.

All my movies are mp4 and the skin uses the images for a great presentation of the movie showing actors and the rest.

Not really sure why items is italicized, they are just background removed images with a transparent background etc.

Thanks for the assist.


Top
 Post subject: Re: Shortening mouse/keystrokes save/export script or method to implem
PostPosted: Fri Apr 07, 2023 6:57 am  (#4) 
Offline
GimpChat Member

Joined: Dec 27, 2022
Posts: 22
As an FYI, here is the source information of what the applications are be used for:

https://kodi.wiki/view/Artwork_types

Breaks down all of it, so I'd have an .xcf of the layered artwork, and then the file export based on requirement of the art type needed be it, keyart, disc art.. etc.

:tyspin


Top
 Post subject: Learning basic string operations on the path
PostPosted: Fri Apr 07, 2023 11:25 am  (#5) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
Great news, Chris! :jumpclap
The following is a basic introduction to Script-Fu.
You may wish to read it to tweak the Rob's script for your application
but not immediately.

Learning basic string operations on the path
Close Gimp. Reopen Gimp then open a picture.
The file extension does not matter.
In this example, "File" > "Open" iconAlSchemist.png

Open the Script-Fu console by the following menu:
"Filters" > "Script-Fu" > "Console"

In the rectangular input box above the "Help" button and at the left of the "Browse" button, copy and paste:
(gimp-version)

Press ENTER to validate the call of the function.
Gimp will reply:
("2.10.34")

The answer is displayed as a list containing only one element: the version number as a string.

Let us display the list of loaded images:
(gimp-image-list)

(1 #(1))

There is one picture in the editor. Its id is 1 if you have previously closed Gimp then reopened Gimp
Otherwise the id could be incremented.
To remember the id of the image, let us define the variable img used as parameter in the Rob's functions.
(define img 1)

Script-Fu replies with the name of the define, that is to say img.

What is the value of img?
img

1

What is the full path of the current image?
save-and-export uses the Gimp API gimp-image-get-filename:
(gimp-image-get-filename img)

("C:\\Tool\\Gimp\\forum\\GimpChat\\iconAlSchemist.png")

We are in Windows because of the double backslash.
Gimp always returns a list.
To get the first element of the list that is to say the string of the path, call the car function.
(car (gimp-image-get-filename img))

"C:\\Tool\\Gimp\\forum\\GimpChat\\iconAlSchemist.png"

Let us save this fullname:
(define fullname (car (gimp-image-get-filename img)))

fullname

If you get the error #<EOF>, verify the number of closing parenthesis.

fullname

"C:\\Tool\\Gimp\\forum\\GimpChat\\iconAlSchemist.png" :coolthup

Copy in the clipboard by Ctrl+C the name of the function gimp-image-get-filename
Click the Browse button in the Script-Fu console.
Then paste the name of the function in the dialog box Script-Fu Procedure Browser.
Gimp will display the help of this function.
Note that there is only one parameter called image.
We defined this parameter with the shorter name "img" as in Rob's script.


Top
 Post subject: Working with the path
PostPosted: Fri Apr 07, 2023 11:40 am  (#6) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
Working with the path

We want to retrieve the filename of the fullname.
So cut the path in a list of tokens removing each backslash.
(strbreakup fullname DIR-SEPARATOR)

("C:" "Tool" "Gimp" "forum" "GimpChat" "iconAlSchemist.png")

The filename is the last item of this list.
(define filename (car (last (strbreakup fullname DIR-SEPARATOR))))

filename

filename

"iconAlSchemist.png"

We want to extract the basename before the dot:
(define basename (car (strbreakup filename ".")))

basename

basename

"iconAlSchemist"

We want to add for example the suffix "-clearart.png"
(define filePng (string-append  basename "-clearart.png"))

filePng

filePng

"iconAlSchemist-clearart.png"

Instead of using (define varName value), let* us introduce local variables:
(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
)

"iconAlSchemist-clearart.png"

However, we want to save .png in the same folder than .xcf:
It is recommended to edit the Scheme code in the free NotePad++.
NotePad++ is able to color the parenthesis by level.
if you specify the language by NotePad++ menu "Language" > "Scheme".
(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
)

"C:\\Tool\\Gimp\\forum\\GimpChat\\iconAlSchemist-clearart.png"

The function reverse is able to reverse the order of items in a list.
(reverse (list "C:" "Tool" "Gimp" "forum" "GimpChat" "iconAlSchemist.png"))

("iconAlSchemist.png" "GimpChat" "forum" "Gimp" "Tool" "C:")

cdr returns the list without its first item.
(cdr (reverse (list "C:" "Tool" "Gimp" "forum" "GimpChat" "iconAlSchemist.png")))

("GimpChat" "forum" "Gimp" "Tool" "C:")

This begins to become complex with this double reverse.
(reverse (cdr (reverse (list "C:" "Tool" "Gimp" "forum" "GimpChat" "iconAlSchemist.png"))))

("C:" "Tool" "Gimp" "forum" "GimpChat")


That is why there is drop-right in 1srfi-001-list.scm from the GimpLambdaLib:
(drop-right (list "C:" "Tool" "Gimp" "forum" "GimpChat" "iconAlSchemist.png") 1)

("C:" "Tool" "Gimp" "forum" "GimpChat")


Top
 Post subject: Vector of Kodi art types
PostPosted: Sat Apr 08, 2023 7:28 am  (#7) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
Vector of Kodi art types

Introducing a vector of art types:
It is like a list but prefixed by sharp "#".
Vector is faster than list and item in a vector can be directly extracted by vector-ref.
By convention, the first letter in the name of a vector is the letter "v".
(define vKodiArtSuffix #("actor" "back" "banner" "characterart" "clearart" "clearlogo" "discart" "fanart" "fanartSharp" "keyart" "landscape" "poster" "spine" "thumb"))

vKodiArtSuffix

We can retrieve a particular art type as a 0-based index in an array:
(vector-ref vKodiArtSuffix 4)

"clearart"

Remember the list of picture ids returned by gimp-image-list.
(gimp-image-list)

(1 #(1))

It is a list having the number of pictures open in Gimp followed by a vector of picture ids.

Let us loop to display all art types.
To simplify, we group both the definition of the function DisplayAllArtType followed by its call.
The function displayln displays a text then returns to the line.
This function is defined in C:\Program Files\GIMP 2\share\gimp\2.0\scripts\palette-export.scm
(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)

DisplayAllArtType
art type 0: actor
art type 1: back
art type 2: banner
art type 3: characterart
art type 4: clearart
art type 5: clearlogo
art type 6: discart
art type 7: fanart
art type 8: fanartSharp
art type 9: keyart
art type 10: landscape
art type 11: poster
art type 12: spine
art type 13: thumb
()

We can synthetize previous posts by the following function having img as parameter.
This function returns a vector composed by the path, the basename and the file extension of the image id "img":
(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)

PathInfoPic#("C:\\Tool\\Gimp\\forum\\GimpChat" "iconAlSchemist" "png")

Reminder : in order that the numerical image id 1 works, you must close Gimp then reopen Gimp then open a picture.

Alternatively, define the following function without parameter:
(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

Now, we can retrieve the id of the current image by the call:
(gimp-image-get-id)

1

We can build a more generic generator of art type path based on the path of the current image of id "img":
(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"C:\\Tool\\Gimp\\forum\\GimpChat\\iconAlSchemist-clearart.png"

With the art type 12: :otb
(KodiSkinPath (gimp-image-get-id) 12)

"C:\\Tool\\Gimp\\forum\\GimpChat\\iconAlSchemist-spine.png" :geek:


Top
 Post subject: Re: Shortening mouse/keystrokes save/export script or method to implem
PostPosted: Sat Apr 08, 2023 11:33 am  (#8) 
Offline
GimpChat Member

Joined: Dec 27, 2022
Posts: 22
oh my... I will be having a good look at this later when I get my house duties and yard stuff done...Nice!

TY!


Top
 Post subject: KodiSave 1.1
PostPosted: Sat Apr 15, 2023 5:18 pm  (#9) 
Offline
GimpChat Member
User avatar

Joined: Oct 23, 2021
Posts: 67
Introducing KodiSave 1.1

Let us synthetize the previous posts by the complete TinyScheme script :drum KodiSave.scm :drum
; 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)


Save KodiSave.scm in C:\Users\YourUserName\AppData\Roaming\GIMP\2.10\scripts\
replacing "YourUserName" by your Windows :proppeng user name. :blind
___________________

Creating KodiSaveArtType.txt for art type 4 = clearart

The new menu "KodiSave" is grayed at the right of the last menu "Help" while there is not any image in Gimp:

Image

  1. In the same folder, you also need to create, for example with NotePad++, a text file called KodiSaveArtType.txt containing the number 4.
    It is the index corresponding to art type "clearart".
    Don't forget to return at the line after the number 4 on the first line.
  2. Alternatively, in Gimp menu "Filter"
  3. "Script-Fu"
  4. "Console"
  5. run:
    (WriteKodiSaveArtType)

    This will create the text file KodiSaveArtType.txt with the index 4 for you. :wizwand

The shortcut for Gimp menu "Filter" > "Script-Fu" > "Console" is ALt+R S C
___________________

Save as .xcf and export as .png using the menu KodiSave

Image

  1. Open or drag&drop your Kodi media .jpg or .png among your 250 items you wish to edit.
  2. Make your modifications in the different layers.
  3. Click the direct menu "KodiSave". The menu becomes blue. :blingbling
  4. Click again the same menu to effectively save the current image as .xcf and export as png according to the current art type.
:bugthumb

To accelerate the process of saving and exporting, there is not any dialog box of confirmation.
The Gimp status bar displays the full filename of the exported file with the art type suffix as .png :sglasses

Note that the saved .xcf is reloaded, then the layers are merged before exporting to .png

In the above screen capture, the old variable "globalArtType" :gaah must be replaced with the call of the function (ReadKodiSaveArtType):
(KodiSkinPath (gimp-image-get-id) (ReadKodiSaveArtType))

will display the path: "C:\\Tool\\Gimp\\forum\\GimpChat\\SaveXcf-ExportPng\\iconAlSchemist-clearart.png"
___________________

Changing the art type to 12 = spine

Image

Let suppose that you wish to change the art type.
Just edit KodiSaveArtType.txt in NotePad++ changing the art type by default 4 by for example 12 for "spine".

You can edit KodiSaveArtType.txt at any time without reloading Gimp or selecting an option in a dialog box.
You do not need to open the Script-Fu console.

However, to explain the Scheme code, every function is called to demonstrate the expected result.
In NotePad++, the shortcut to capture a Scheme expression in parenthesis is Ctrl+Alt+B when you are on a given parenthesis.

  1. Let us recall what is the art type by default using:
    (ReadKodiSaveArtType)

    The result is the index 4 that we can convert in a name by:
    (CurrentArtType)

    displaying "clearart".
  2. You are asked to edit the art type.
  3. Go to NotePad++ and replace the old index 4 by the new index 12 in KodiSaveArtType.txt :keybdtype
    (CurrentArtType)

    displays "spine".
  4. The Scheme instruction "file-glob" is equivalent to "dir" in a Windows console or "Get-ChildItem" in PowerShell.
    So you can list the existing file before saving.
  5. Click KodiSave. :idea:
  6. Read in the Gimp status bar what has been exported.
    Navigate in the File Explorer to see the saved .xcf and the exported .png
  7. Optionally, recall "file-glob" for confirmation :yup

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? :pengy


Last edited by AlSchemist on Sun Apr 16, 2023 5:24 am, edited 1 time in total.

Top
 Post subject: Re: KodiSave 1.0
PostPosted: Sat Apr 15, 2023 7:24 pm  (#10) 
Offline
GimpChat Member

Joined: Dec 27, 2022
Posts: 22
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? :pengy


This has been on the back of my mind, wow, the pictures look great!

The naming, it "depends" on if a flat folder is used (everything in a single folder > not recommended for this) or movie by date. Without the long history and debate of one over the other, most follow movie by date format.

What this means, a movie.. i.e. Aliens, Avatar, Zombieland.... etc. will have its own unique folder to "store" all of the relevant images, trailer.mp4, movie.mp4/mkv, nfo files....etc...all of that which is unique to that particular movie..will reside in a "root" folder and each movie will be named like:

Movies << Root folder
........Aliens (1986) << Subfolder in Root
........Avatar (2009) << Subfolder in Root
........Zombieland (2009) << Subfolder in Root

When new movies are added, more folders are added by movie name etc. TV shows follow similar formatting with the caveat that it will have subfolders to hold each "season" of that series but mirrors the Movies file structure also.

So that is the naming aspect of your inquiry.

Why are some jpg vs png? This is very specific to the "skin" used by Kodi, some skins will utilize all the artwork others will only use some.

Anything png is required to have an alpha transparency layer and the background must be transparent. The discart, clearart, clearlogo pngs are used as overlays in movie library navigation so when you browse over the movie, the clearlogo will display center bottom. The clearart pops up when you pause the movie in the lower left and in the library info mode, the discart "spins" in from the right side of the screen. All pngs are overlayed over other layers in the skin and make for a great visual impact on the user experience and also provides key elements of what the movie is about (even though most will already know anyway, more of an experience thing).

The .jpg items poster, landscape, keyart where these items do not overlay the video media itself and the user would not want to be see anything behind it, so no transparency is needed. The landscape is used in the up next module so when you are near the end of whatever media, Kodi's skin will use it as a preview of what is coming up (kind of like Netflix) and it displays the movie key elements and logo so the user can say yes or no....etc. Keyart isn't used much, but is required for some skins when it displays in different format modes such as banner, keyart, slideshows, rolling slideshow etc.

So it really depends on the skin and how much the images are used, but ultimately programs like tinymediamanager, Media Companion or other apps will use sites like fanart.tv to "scrape" (download the images in the proper size and format from the website if they are present during the scape time) the data when new movies are added. It is an entire eco system of people creating the artwork.....not kidding.....for free...and free to everyone at any time. One of the true altruistic endeavors by a community that enjoys using Kodi (or other media servers that can use the artwork) as a media server for their media.

While Kodi has a bad rap about illegal stuff, their charter changed. It really does a great job as a media server.

Anyway, sorry for the long response, hope this helps your inquiry.

:)


Top
 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 1637 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 1627 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 1627 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 1627 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 1627 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 1627 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 1598 times ]

By defaut the FanArt only numerical suffix is zero:

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

it is not added after "-fanart".

Attachment:
KodiSaveFanArt1.png
KodiSaveFanArt1.png [ 133.93 KiB | Viewed 1598 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 1574 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 1574 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 1573 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 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