Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
gegl filters in batch processing
#1
I am trying to call a gegl edge detect filter repeatedly in a while loop as here


Code:
        (while (not (null? filepaths))        
                       ;some stuff    
                       (gimp-drawable-merge-new-filter
            2                         ; The drawable to apply the filter to
            "gegl:edge"                        ; The name of the GEGL operation
            0                                  ; The merge-mode (0 for normal)
            LAYER-MODE-REPLACE                 ; The layer mode (e.g., replace, normal, etc.)
            100.0                              ; The opacity (0.0 to 100.0)
            "amount" 2.0                       ; Parameter: amount of edge detection
            "border-behavior" "none"           ; Parameter: how to handle image borders
            "algorithm" "sobel"                ; Parameter: the edge detection algorithm
            )
                        ;some more stuff
          )
 it works but only on the first image in the batch. Is there something I need to do to get it to work on all the images?
Reply
#2
I don't see where your code loads a new image in each iteration of the loop. My first call would be to add a print statement or gimp-message call to check that the iteration happens, and on what filepath and image ID.

On a different matter, in Gimp3 script-fu has lost most of its advantages over Python, all that is left is a contrived syntax and plenty of restrictions.
Reply
#3
Here's the whole script

Code:
(define (script-fu-edge input-path output-path)
;(gimp-message "starting up")
;(gimp-message (string-append "path = " input-path))

(let* (
        (filepaths (car (file-glob (string-append input-path "*.png") 1)))
        (filename "")
        (full_in_path "")
        (full_out_path "")
    );end of variable definitions in outer block
        
        (while (not (null? filepaths))
            (set! filename (substring (car filepaths) (string-length input-path) (string-length (car filepaths))))
            ;(gimp-message filename)
            (set! full_in_path (string-append input-path filename))
            (set! full_out_path (string-append output-path filename))
            ;(gimp-message (string-append "Input path = " full_in_path))
            ;(gimp-message (string-append "Output path = " full_out_path))
            (set! filepaths (cdr filepaths))
            (let* (
            (image (car (file-png-load RUN-NONINTERACTIVE full_in_path full_in_path )))
            (drawable (car (gimp-image-get-layers image)))
            )
            (gimp-image-convert-grayscale image)
            (pdb-gimp-edge-detect drawable EDGE-DETECT-SOBEL 1 0)
            (gimp-drawable-merge-new-filter
            2                         ; The drawable to apply the filter to
            "gegl:edge"                        ; The name of the GEGL operation
            0                                  ; The merge-mode (0 for normal)
            LAYER-MODE-REPLACE                 ; The layer mode (e.g., replace, normal, etc.)
            100.0                              ; The opacity (0.0 to 100.0)
            "amount" 2.0                       ; Parameter: amount of edge detection
            "border-behavior" "none"           ; Parameter: how to handle image borders
            "algorithm" "sobel"                ; Parameter: the edge detection algorithm
            )
            (gimp-message (string-append "saving file " full_out_path))
            (gimp-file-save RUN-NONINTERACTIVE image full_out_path full_out_path -1)
            )
        ); end of while
); end of outer block
); end of function

 (script-fu-register
   "script-fu-edge"                        ;function name
   "Edge Image"                                  ;menu label
   "Converts an image to edge Image\
     and saves the result as a new file"       ;description
   "Peter McGuinness"                             ;author
   "copyright 2025, Peter McGuinness"        ;copyright notice
   "August 6, 2025"                          ;date created
   "*"                                      ;image type that the script works on
   SF-STRING      "Input path"           "/users/public/test/images/"  
SF-STRING      "Output path"        "/users/public/test/edges/"  

 )
 (script-fu-menu-register "script-fu-edge" "<Image>/Filters/Chameleon")
Reply
#4
So if that is assumed to attempt to loop, my first suspect is the GEGL call, with a very suspicious-looking  "border-behavior" "none". Because according to the (rather short, I'll admit) doc, that field is an "enum", so normally integer values (to which a mnemonic name is given). So given that "none" is the first in the list, I would try to replace it with an integer 0.

In any case, you should have a error message in the console when you run this. Run with gimp-console.exe or else, and report the error there if you want more help (or try the call in the script-fu console).
Reply
#5
(08-11-2025, 02:21 PM)pyjamaslug Wrote: Here's the whole script

Code:
(define (script-fu-edge input-path output-path)
;(gimp-message "starting up")
;(gimp-message (string-append "path = " input-path))

(let* (
        (filepaths (car (file-glob (string-append input-path "*.png") 1)))
        (filename "")
        (full_in_path "")
        (full_out_path "")
    );end of variable definitions in outer block
        
        (while (not (null? filepaths))
            (set! filename (substring (car filepaths) (string-length input-path) (string-length (car filepaths))))
            ;(gimp-message filename)
            (set! full_in_path (string-append input-path filename))
            (set! full_out_path (string-append output-path filename))
            ;(gimp-message (string-append "Input path = " full_in_path))
            ;(gimp-message (string-append "Output path = " full_out_path))
            (set! filepaths (cdr filepaths))
            (let* (
            (image (car (file-png-load RUN-NONINTERACTIVE full_in_path full_in_path )))
            (drawable (car (gimp-image-get-layers image)))
            )
            (gimp-image-convert-grayscale image)
            (pdb-gimp-edge-detect drawable EDGE-DETECT-SOBEL 1 0)
            (gimp-drawable-merge-new-filter
            2                         ; The drawable to apply the filter to
            "gegl:edge"                        ; The name of the GEGL operation
            0                                  ; The merge-mode (0 for normal)
            LAYER-MODE-REPLACE                 ; The layer mode (e.g., replace, normal, etc.)
            100.0                              ; The opacity (0.0 to 100.0)
            "amount" 2.0                       ; Parameter: amount of edge detection
            "border-behavior" "none"           ; Parameter: how to handle image borders
            "algorithm" "sobel"                ; Parameter: the edge detection algorithm
            )
            (gimp-message (string-append "saving file " full_out_path))
            (gimp-file-save RUN-NONINTERACTIVE image full_out_path full_out_path -1)
            )
        ); end of while
); end of outer block
); end of function

 (script-fu-register
   "script-fu-edge"                        ;function name
   "Edge Image"                                  ;menu label
   "Converts an image to edge Image\
     and saves the result as a new file"       ;description
   "Peter McGuinness"                             ;author
   "copyright 2025, Peter McGuinness"        ;copyright notice
   "August 6, 2025"                          ;date created
   "*"                                      ;image type that the script works on
   SF-STRING      "Input path"           "/users/public/test/images/"  
SF-STRING      "Output path"        "/users/public/test/edges/"  

 )
 (script-fu-menu-register "script-fu-edge" "<Image>/Filters/Chameleon")

pdb-gimp-edge-detect isn't in gimp 3.02 (that I was using) and anyway surly you have the call to gimp-drawable-merge-new-filter with "gegl:edge"  to do the edge detection. That's what post #1 asks about.

In the call to gimp-drawable-merge-new-filter:

You hard coded a drawable id of 2. You should not do this as you don't know what the id's will be. You likely got away with it for the first image but for subsequent images it will be different.

Opacity goes from 0 to 1.0 not to 100.0.

It would be better to use the v3 dialect of ScriptFu but I've stuck with what you have used to minimise the differences.  The changes I made to your code to get "gegl:edge" working on all images are (< marks old lines and > new lines):

Code:
23c23,24
<             (drawable (car (gimp-image-get-layers image)))
---
>             (layers (car (gimp-image-get-layers image)))
>             (layer (vector-ref layers 0)) ; Assumes you want the top root layer.
26c27
<             (pdb-gimp-edge-detect drawable EDGE-DETECT-SOBEL 1 0)
---
>         ;   (pdb-gimp-edge-detect drawable EDGE-DETECT-SOBEL 1 0)
28c29
<             2                         ; The drawable to apply the filter to
---
>             layer                              ; The drawable to apply the filter to
32c33
<             100.0                              ; The opacity (0.0 to 100.0)
---
>             1.0                                ; The opacity (0.0 to 100.0)
Reply
#6
All right! That now works, sorry about the random call to pdp-gimp-edge-detect. That was just me trying to find something that might work and forgetting to comment it out when it didn’t. So thanks for reading the code more carefully than I did.
I now need to more fully understand drawables and layers because that missing bit of understanding was what caused me to use the hard coded value that was causing the problem.
Thanks again.
Reply


Forum Jump: