Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
script-fu - how to refer to the active image?
#1
Hi, I'm a newbie. I can't figure out how to refer to the active image in a non-interactive script. The example scripts I find all refer to either a new image, or an image loaded from disk, or looping through the image list, or assuming you're working on the rightmost image, or the image comes as a parameter from the dialog (for interactive scripts). I haven't been successful in locating an example that just uses an already opened active image.

So if i have an image open and active, and I want a non-interactive script to reduce opacity of that selected image with a fixed amount and then save the image, how do i refer to the image (and drawable)?


tnx!
Reply
#2
(06-26-2020, 04:36 AM)stabilo Wrote: Hi, I'm a newbie. I can't figure out how to refer to the active image in a non-interactive script. The example scripts I find all refer to either a new image, or an image loaded from disk, or looping through the image list, or assuming you're working on the rightmost image, or the image comes as a parameter from the dialog (for interactive scripts). I haven't been successful in locating an example that just uses an already opened active image.

So if i have an image open and active, and I want a non-interactive script to reduce opacity of that selected image with a fixed amount  and then save the image, how do i refer to the image (and drawable)?


tnx!

Let's be clear on the vocabulary:
  • interactive: the user interacts with Gimp using the UI
  • non-interactive: Gimp is called from the command line with parameters defining an operation to execute, the UI oesn't even need to show up.
So, you are always in the "interactive" case, the question being whether or not the script pops up a dialog when called.

The secret is:
  • If the first parameter in your script is an image (SF_IMAGE in Scheme, PF_IMAGE in Python) then it is assumed to be the current image (in single window mode, the one in the active tab, in multiple windows mode, the one in the window where you used the menu). Since it is implicitly determined, the auto-generated dialog doesn't include a widget to select it.
  • If the second parameter is a "drawable" (a "drawable" is anything on which you can paint: layer, layer mask, or channel)(SF_DRAWABLE/PF_DRAWABLE) then it is assumed to be the current active drawable for the image: active layer or layer mask or channel. And here also, since it is implicitly determined, the auto-generated dialog doesn't include a widget to select it.
So if you create a script that just takes an image and a drawable (or just an image), the script executes right away without showing a dialog. In some cases, if you re-run the script (Ctr-shift-F),  it can need to ask for and image or drawable and you will get an auto-generated popup. And if you create a script that takes and image, a drawable, and an opacity, the dialog will only have a widget for the opacity.

Final note: you don't reduce the opacity of an image but the opacity of a layer in the image, so you will need both arguments.
Reply
#3
(06-26-2020, 05:42 AM)Ofnuts Wrote: Thanks for replying so quickly!

Quote:Let's be clear on the vocabulary:
OK, thanks for clearing that up Smile



Quote:So if you create a script that just takes an image and a drawable [...], the script executes right away without showing a dialog.
I'll get the terminology all wrong here too, but this is where I was confused: it wasn't clear to me that I needed to call a dialog with SF-IMAGE and SF-DRAWABLE that then would not be shown, but that still passes on the parameters to the script.

I've got it working now, thank you!
Reply
#4
I have a problem related to this, so I hope it is okay if I reply in this thread.

I tried to modify this script to get a reference if it is started while an image is active.

These parts got modified.

1.

an additional line


Code:
SF_IMAGE       "image"         "whatever"   ;image variable

in script-fu-register, so it now looks like this

Code:
           ""                     ;image type that the script works on
           SF_IMAGE       "image"         "whatever"   ;image variable
           SF-STRING      "Text"          "Text Box"   ;a string variable

2.
Code:
(define (script-fu-text-box inText inFont inFontSize inTextColor inBufferAmount) ...

got modified to


Code:
(define (script-fu-text-box inImage inText inFont inFontSize inTextColor inBufferAmount) ...


However after saving this and  refreshing the scripts the menu entry for the script disappeared. Now I'm stuck.
Reply
#5
(12-10-2022, 12:10 PM)flauapaua Wrote: ...
However after saving this and  refreshing the scripts the menu entry for the script disappeared. Now I'm stuck.

The menu entry disappearing means that GIMP has identified a problem with the script. If you can run GIMP from a terminal it should show you what the problem is (you will probably have to search through quite a lot of output but if you copy and paste the contents of the terminal window into a text editor you could search for the name of your script).
Reply
#6
(12-10-2022, 04:50 PM)programmer_ceds Wrote: If you can run GIMP from a terminal it should show you what the problem is (you will probably have to search through quite a lot of output but if you copy and paste the contents of the terminal window into a text editor you could search for the name of your script).
It seems actually not so bad. This is what I get
Code:
:~$ /usr/bin/gimp

(script-fu:17270): GLib-WARNING **: 22:42:02.835: (../../../glib/gerror.c:761):g_error_new_valist: runtime check failed: (domain != 0)
script-fu-Warnung: Fehler beim Laden von /home/g2425/.config/GIMP/2.10/scripts/example-text-box.scm:

Error: (/home/g2425/.config/GIMP/2.10/scripts/example-text-box.scm : 18) eval: unbound variable: SF_IMAGE



(script-fu:17270): GLib-WARNING **: 22:42:02.835: (../../../glib/gerror.c:761):g_error_new_valist: runtime check failed: (domain != 0)
script-fu-Warnung: Fehler beim Laden von /home/g2425/.config/GIMP/2.10/scripts/test-safe-png.scm:

Error: (/home/g2425/.config/GIMP/2.10/scripts/test-safe-png.scm : 17) eval: unbound variable: SF_IMAGE

I tried to attach the whole script to this post, but it tells me, that this type of file is not allowed.
Reply
#7
(12-10-2022, 09:49 PM)flauapaua Wrote: I tried to attach the whole script to this post, but it tells me, that this type of file is not allowed.

You can copy-paste the text in a [code] bracket, that you can create clicking the "code" icon above  the composer window ( the <> over scroll, 5th icon from right).

You can also put it in a ZIP an attach the ZIP.

Also, if you put a SF_IMAGE, the image type should be "*", and of course the script won't be enabled until you have an image open (but of course it will always appear in the menus).
Reply
#8
(12-11-2022, 07:29 AM)Ofnuts Wrote: Also, if you put a SF_IMAGE, the image type should be "*", and of course the script won't be enabled until you have an image open (but of course it will always appear in the menus).
So this goes into the second column in
Code:
script-fu-register
I assume.
Code:
 (script-fu-register
           "script-fu-text-box"                        ;func name
           "Text Box"                                  ;menu label
           "Creates a simple text box, sized to fit\
             around the user's choice of text,\
             font, font size, and color."              ;description
           "Michael Terry"                             ;author
           "copyright 1997, Michael Terry;\
             2009, the GIMP Documentation Team"        ;copyright notice
           "October 27, 1997"                          ;date created
           ""                     ;image type that the script works on
           SF_IMAGE       "*"         "whatever"   ;image variable
           SF-STRING      "Text"          "Text Box"   ;a string variable
           SF-FONT        "Font"          "Charter"    ;a font variable
           SF-ADJUSTMENT  "Font size"     '(50 1 1000 1 10 0 1)
                                                       ;a spin-button
           SF-COLOR       "Color"         '(0 0 0)     ;color variable
           SF-ADJUSTMENT  "Buffer amount" '(35 0 100 1 10 1 0)
                                                       ;a slider
 )
 (script-fu-menu-register "script-fu-text-box" "<Image>/File/Create/Text")
 (define (script-fu-text-box inImage inText inFont inFontSize inTextColor inBufferAmount)
   (let*
     (
       ; define our local variables
       ; create a new image:
       (theImageWidth  10)
       (theImageHeight 10)
       (theImage)
       (theImage
                 (car
                     (gimp-image-new
                       theImageWidth
                       theImageHeight
                       RGB
                     )
                 )
       )
       (theText)             ;a declaration for the text
       (theBuffer)           ;create a new layer for the image
       (theLayer
                 (car
                     (gimp-layer-new
                       theImage
                       theImageWidth
                       theImageHeight
                       RGB-IMAGE
                       "layer 1"
                       100
                       LAYER-MODE-NORMAL
                     )
                 )
       )
     ) ;end of our local variables
     (gimp-image-add-layer theImage theLayer 0)
     (gimp-context-set-background '(255 255 255) )
     (gimp-context-set-foreground inTextColor)
     (gimp-drawable-fill theLayer BACKGROUND-FILL)
     (set! theText
                   (car
                         (gimp-text-fontname
                         theImage theLayer
                         0 0
                         inText
                         0
                         TRUE
                         inFontSize PIXELS
                         "Sans")
                     )
       )
     (gimp-message "\nHello World")
     (set! theImageWidth   (car (gimp-drawable-width  theText) ) )
     (set! theImageHeight  (car (gimp-drawable-height theText) ) )
     (set! theBuffer (* theImageHeight (/ inBufferAmount 100) ) )
     (set! theImageHeight (+ theImageHeight theBuffer theBuffer) )
     (set! theImageWidth  (+ theImageWidth  theBuffer theBuffer) )
     (gimp-image-resize theImage theImageWidth theImageHeight 0 0)
     (gimp-layer-resize theLayer theImageWidth theImageHeight 0 0)
     (gimp-layer-set-offsets theText theBuffer theBuffer)
     (gimp-display-new theImage)
     (list theImage theLayer theText)
   )
 )

Tough luck however. Gimp still complains about the unbound variable znd shows no menu entry. Even if I create an image by the way.

Code:
(script-fu:12523): GLib-WARNING **: 18:17:28.269: (../../../glib/gerror.c:761):g_error_new_valist: runtime check failed: (domain != 0)
script-fu-Warnung: Fehler beim Laden von /home/g2425/.config/GIMP/2.10/scripts/example-text-box.scm:

Error: (/home/g2425/.config/GIMP/2.10/scripts/example-text-box.scm : 18) eval: unbound variable: SF_IMAGE
Reply
#9
The "*" should be in the line before the SF-IMAGE line. Specifying "" means that the script will be enabled whether or not there is an active image - which makes the SF-IMAGE parameter redundant - probably not what you want.

A minor correction to what Ofnuts said - the script will only appear in the menu if GIMP hasn't detected a problem with it. In your case GIMP has detected a problem so no script in the menu.

It might be worth you looking at the standard Script-Fu scripts for V2.10 - the latest versions are at:

https://gitlab.gnome.org/GNOME/gimp/-/tr...fu/scripts

If GIMP is open and you make a change to a Python script it will take effect the next time you run the script (you don't have to stop and restart GIMP). However, with a Script-Fu script any changes that you make to the script will not take effect until you either stop and restart GIMP or use "Filters/Script-Fu/Refresh Scripts" (note that this second option doesn't currently work with GIMP V2.99 - it simply removes all Script-Fu scripts from the menus!)
Reply
#10
(12-13-2022, 01:57 PM)programmer_ceds Wrote: The "*" should be in the line before the SF-IMAGE line.

So, like this, right?
Code:
           "*"                     ;image type that the script works on
           SF_IMAGE       ""         "whatever"   ;image variable
However the error remains the same

(12-13-2022, 01:57 PM)programmer_ceds Wrote: Specifying "" means that the script will be enabled whether or not there is an active image - which makes the SF-IMAGE parameter redundant - probably not what you want.
Actually I don't care at this point. I want a reference to the image, if there is an image. If I get a NULL or whatever undefined value, in case nothing is open, is unimportant to me right now.

(12-13-2022, 01:57 PM)programmer_ceds Wrote: A minor correction to what Ofnuts said - the script will only appear in the menu if GIMP hasn't detected a problem with it. In your case GIMP has detected a problem so no script in the menu.
Ok.
I mean, not ok: I want to get rid of this problem. But I understand, what you are saying.

(12-13-2022, 01:57 PM)programmer_ceds Wrote: It might be worth you looking at the standard Script-Fu scripts for V2.10 - the latest versions are at:

https://gitlab.gnome.org/GNOME/gimp/-/tr...fu/scripts
I don't understand them. E.g there is https://gitlab.gnome.org/GNOME/gimp/-/bl...-photo.scm
which might be similar to what I want, judging from the inImage in
Code:
(define (script-fu-old-photo inImage inLayer inDefocus inBorderSize inSepia inMottle inCopy)
But I see nothing there, which says, that the variable
Code:
inImage
is of type SF_IMAGE. How does gimp know, that it is expected to put a reference to the current image into that variable?

(12-13-2022, 01:57 PM)programmer_ceds Wrote: However, with a Script-Fu script any changes that you make to the script will not take effect until you either stop and restart GIMP or use "Filters/Script-Fu/Refresh Scripts" (note that this second option doesn't currently work with GIMP V2.99 - it simply removes all Script-Fu scripts from the menus!)

I'll do the restart thing to be on the secure side.
If I regress the script to 

Code:
           "*"                     ;image type that the script works on
;            SF_IMAGE       ""         "whatever"   ;image variable
           SF-STRING      "Text"          "Text Box"   ;a string variable
           SF-FONT        "Font"          "Charter"    ;a font variable
           SF-ADJUSTMENT  "Font size"     '(50 1 1000 1 10 0 1)
                                                       ;a spin-button
           SF-COLOR       "Color"         '(0 0 0)     ;color variable
           SF-ADJUSTMENT  "Buffer amount" '(35 0 100 1 10 1 0)
                                                       ;a slider
 )
 (script-fu-menu-register "script-fu-text-box" "<Image>/File/Create/Text")
 (define (script-fu-text-box inText inFont inFontSize inTextColor inBufferAmount)

it gets through quite nicely.  But I want to write a script, that operates on an existing image.
Reply


Forum Jump: