You are here

A specific and some general questions to Script-Fu

Hi there,
I'm a beginner if it comes to use GIMP or scripting.
My intention is to resize all images given in a directory into different sizes (1280, 1024 etc...) e.g. open the images, apply mod, save image. I used a basic script found here on the website, but didn't achive the desired results as I struggle with Scheme and Skript-Fu.

1)
The first problem I've got is that the resize calculation to scale the image yields a strange results:
(set! h (floor (/ height (/ width w)))) will result in an image height of h = 1 instead of the proper value (e.g. 721). I assume this might be a data type conversion problem (float to integer) ?
-> how are data types handled best in Scheme ?
-> is there any good way to check the results (debuging) ? e.g. (gimp-message), writing on separate image ?

2)
Then I had a strange phenomenon, when using a second image variable e.g. (set! tmp image) and applied mods on this variable. saving was possible, but resizing not (or flipping). If I used the origina image all was possivble. Anyone with same experience ?

3)
Next, I assume the Script-Fu console would be great tool to learn about Scheme and GIMP, but how do I get a reference to an actually opened image to impose the mods live ?

4)
From my little experience it seems as ever gimp function needs to be within a (car ) expression (get head element)...correct ?

Sorry to write that many (silly?) questions but I didn't find quite a good source for them.

Thanks for any help,
Cheers Fu_sion

Here's my full script:
;============================================
; Script definition (main)
;============================================
(define (script_fu_batch_resizeImg inDir inLoadType )
(let*
( ;define variables
(varLoadStr 0)
(varSaveStr 0)
(image 0)
(w 1)
(h 1)
(width 1280)
(height 1280)
(counter 0)
(newfilename 0)
(filename 0)
(varFileList 0)
(handler (car (gimp-message-get-handler)))
)
(set! varLoadStr
(cond
(( equal? inLoadType 0 ) ".jpg" )
(( equal? inLoadType 1 ) ".bmp" )
(( equal? inLoadType 2 ) ".png" )
(( equal? inLoadType 3 ) ".gif" )
(( equal? inLoadType 4 ) ".xcf" )
)
)

;Get list of filenames in directory matching the filename string (parameter 1 = filename encoding)
(set! varFileList (cadr (file-glob (string-append inDir DIR-SEPARATOR "*" varLoadStr) 1)))

;loop over all list elements
(while (not (null? varFileList))

;get next image name from list
(set! filename (car varFileList))
(+ counter 1)

;open image (call automatically correct file loader, run in non-interactive mode)
(set! image (car (gimp-file-load 1 filename filename)))

;resize to 1280px (larger side) if possible
(set! width (car(gimp-image-width image)))
(set! height (car(gimp-image-height image)))
(cond
((>= width height)
(if (>= width 1280)
(set! w 1280)
(set! h (floor (/ height (/ width w))))
(gimp-message (string-append "w=" (number->string w) ", h=" (number->string h)))
)
)
((< width height)
(if (>= height 1280)
(set! h 1280)
(set! w (floor (/ height (/ width h))))
(gimp-message (string-append "h=" (number->string h) ", w=" (number->string w)))
)
)
(else)
)

;Resize image
(gimp-image-scale image w h)

;save image
(set! newfilename (string-append (substring filename 0 (- (string-length filename) 4)) "_" (number->string counter) ".jpg"))
(saveImg image newfilename)

;delete used image and remove image name from list
(gimp-image-delete image)
(set! varFileList (cdr varFileList))
)
)
)

;============================================
; Function definitions
;============================================
(define (saveImg inImg inName )
(let*
( ;define our variables
(drawable 0)
)

(gimp-image-flatten inImg)
(set! drawable (car (gimp-image-get-active-layer inImg)))
(gimp-image-clean-all inImg)
(gimp-file-save 1 inImg drawable inName inName)
)
)

;============================================
; Script registering
;============================================
(script-fu-register "script_fu_batch_resizeImg"
"/Filters/MyScript/Resize Img"
"Resize Img's in a specified folder"
"Andreas Baechtold based on script by Emily Smirle"
"Andrea Baechtold"
"August 2010"
""
SF-DIRNAME "Load from" ""
SF-OPTION "Load File Type" (list "jpg" "bmp" "png" "gif" "xcf")
)

Forums: 

I think you have a problem with the if:

(if (>= width 1280)
(set! w 1280)
(set! h (floor (/ height (/ width w))))
(gimp-message (string-append "w=" (number->string w) ", h=" (number->string h)))
)

It should be:

(if (condition) (statement for true) (statement for false))

To have more than one statement in the if you need to use (begin ...)

so:

(if (condition)
(begin
(stuff true 1)
(stuff true 2)
)
(begin
(stuff false 1)
(stuff false 2)
)
)

If you just watn to do a bunch of stuff for true (or false), consider:

(when (condition)
(many)
(statements)
(here)
)

or the oposite
(unless (condition)
(many)
(statements)
(here)
)

-Rob A>

Hey Rob and fellows...
Sorry to not have said that earlier, but let me thank you so much... have not yet gone through all of your responses in detail, but you certainly helped me with your first comment, i got my script running with that and now all my vacation images (over 500) have been sized and processed as I wished...
I'll read through your comments again and check on scheme to have a nice script that may be posted here for others who look for something similar or want to get more into it...
nice to have such a forum and decent answers...
Fu-sion

3)
Next, I assume the Script-Fu console would be great tool to 
learn about Scheme and GIMP, but how do I get a reference to 
an actually opened image to impose the mods live ?

I would recommend opening one of the dialogs in the commands under the Image Menu (e.g., Image->Scale Image...). At the top of the dialog you will see the name of the image with a hyphen and a number appended to its end (e.g., "girlygirl.jpg-26"). The number after the hyphen is the image ID. (Note: layer IDs can similarly be discovered using dialogs of commands under the Layer Menu.)

4)
From my little experience it seems as ever gimp function needs 
to be within a (car ) expression (get head element)...correct ?

This is true for all PDB functions. Scheme functions are only able to return one thing (though that one thing may be a list of many things). For all PDB functions, the return values are placed in a list, even if there is only a single return value (e.g., 'gimp-image-width').

Thanks for your input saulgoode. Didn't know all of that. In the meantime I found something else that is also very useful. There is a GIMP PDB function called (Gimp-Image-List) which will return a list with 2 elements. First element is the number of actually opened images in GIMP, and second element is a list containing the IDs of these images... This is a good starting point to impose Scheme PDB functions on an active image. Here is an example copied from the script-fu console:

> (gimp-image-list)
(3 #( 3 2 1 ))
> (gimp-image-rotate 2 0)
(#t) -> image with ID 2 was rotated

As well you should be able to see the ID of an Image in the window name e.g. sunset.jpg-2.0 (RGB, 1 layer) 1280x768 - GIMP (ID = 2)

Thanks everybody, Fu_sion

Subscribe to Comments for "A specific and some general questions to Script-Fu"