Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
changing active layers
#1
Hello all. I just got into gimp and also have very little knowledge in scripting.

I have 2 black and white files with little difference.
I want to compare them using gimp.
For the process, I import the 2 files in different layers.
Then, using color exchange, I change the black to blue in one layer.
Then change black to red in the other layer. 
The blending for the second layer will be multiply.

My script below gets an error when setting the second layer active I think.

(define (script-fu-set-active-layers image layer)
  (let* (
    (layer-list (gimp-image-get-layers image))
    (layer1 (car layer-list))
    (layer2 (cadr layer-list))
  )
    (gimp-image-set-active-layer image layer1)
    (plug-in-exchange RUN-NONINTERACTIVE image layer 0 0 0 255 0 0 0 0 0)
    (gimp-image-set-active-layer image layer2)
    (plug-in-exchange RUN-NONINTERACTIVE image layer 0 0 0 0 0 255 0 0 0)
  )
  (gimp-displays-flush)
)

Thank you very much.
Reply
#2
(01-29-2023, 06:54 AM)salamander017 Wrote: Hello all. I just got into gimp and also have very little knowledge in scripting.

I have 2 black and white files with little difference.
I want to compare them using gimp.
For the process, I import the 2 files in different layers.
Then, using color exchange, I change the black to blue in one layer.
Then change black to red in the other layer. 
The blending for the second layer will be multiply.

My script below gets an error when setting the second layer active I think.

(define (script-fu-set-active-layers image layer)
  (let* (
    (layer-list (gimp-image-get-layers image))
    (layer1 (car layer-list))
    (layer2 (cadr layer-list))
  )
    (gimp-image-set-active-layer image layer1)
    (plug-in-exchange RUN-NONINTERACTIVE image layer 0 0 0 255 0 0 0 0 0)
    (gimp-image-set-active-layer image layer2)
    (plug-in-exchange RUN-NONINTERACTIVE image layer 0 0 0 0 0 255 0 0 0)
  )
  (gimp-displays-flush)
)

Thank you very much.

It might help if you gave details of the error message.
Reply
#3
(01-29-2023, 10:57 AM)programmer_ceds Wrote: It might help if you gave details of the error message.

Hello, thank you for your time.
Regarding that, the error says:
  GIMP Error
Execution error for 'Set active layers':
Error: Invalid type for argument 2 to gimp-image-set-active-layer
Reply
#4
(01-29-2023, 12:47 PM)salamander017 Wrote:
(01-29-2023, 10:57 AM)programmer_ceds Wrote: It might help if you gave details of the error message.

Hello, thank you for your time.
Regarding that, the error says:
  GIMP Error
Execution error for 'Set active layers':
Error: Invalid type for argument 2 to gimp-image-set-active-layer
I think that the problem is that gimp-image-get-layers returns two parameters - the first is the number of layers and the second is an int32 array of the layer IDS (see the description of gimp-image-get-layers in the PDB browser).

So your code is assigning the number of layers to layer1, not the ID of the first layer.

Try replacing the assignments that set layer1 and layer2 with:

(num_layers (cad (gimp-image-get-layers image)))
(layers (cadr (gimp-image-get-layers image)))

then:

(layer1 (aref layers 0))
(layer2 (aref layers 1))



However, it would be better code to set layer1 and layer2 (using the set! statement) after your let* statement - having checked that the image does actually have 2 (or possibly, depending on your needs) at least 2 layers before proceeding - report an error if there are not 2 layers, then your script can fail gracefully if it activated with just the one layer.
Reply
#5
You don't need to set active layers... The layer argument of the (plugin-exchange) is the layer on which it will act, so this should be layer1 or layer2.

Otherwise, without changing colors, if you change the top layer to Difference blend mode, you will get white spots where the layers differ.
Reply
#6
(01-29-2023, 05:25 PM)programmer_ceds Wrote:
(01-29-2023, 12:47 PM)salamander017 Wrote: Hello, thank you for your time.
Regarding that, the error says:
  GIMP Error
Execution error for 'Set active layers':
Error: Invalid type for argument 2 to gimp-image-set-active-layer
I think that the problem is that gimp-image-get-layers returns two parameters - the first is the number of layers and the second is an int32 array of the layer IDS (see the description of gimp-image-get-layers in the PDB browser).

So your code is assigning the number of layers to layer1, not the ID of the first layer.

Try replacing the assignments that set layer1 and layer2 with:

(num_layers (cad (gimp-image-get-layers image)))
(layers (cadr (gimp-image-get-layers image)))

then:

(layer1 (aref layers 0))
(layer2 (aref layers 1))



However, it would be better code to set layer1 and layer2 (using the set! statement) after your let* statement - having checked that the image does actually have 2 (or possibly, depending on your needs) at least 2 layers before proceeding - report an error if there are not 2 layers, then your script can fail gracefully if it activated with just the one layer.
Thank you very much for the explanation.


Is there a way to run gimp procedures using the script-fu console? Or, how do I test what parameters are returned when using a gimp procedure?

(01-29-2023, 09:10 PM)Ofnuts Wrote: You don't need to set active layers...  The layer argument of the (plugin-exchange) is the layer on which it will act, so this should be layer1 or layer2.

Otherwise, without changing colors, if you change the top layer to Difference blend mode, you will get white spots where the layers differ.

Oh, thank you very much for that. I have modified the code based on your suggestion. But now, when running the script, a dialog pops up and makes me choose between the layers.
But I prefer if it did not.
If I choose the top layer, only the blue to the top is applied. If I choose the bottom layer, all is applied correctly. (the top layer must be active)
When the active layer is the second layer. The colors are reversed and multiply is applied to the bottom layer instead.

(define (script-fu-gimpcompare image layer1 layer2)
  (plug-in-exchange RUN-NONINTERACTIVE image layer1 0 0 0 0 0 255 0 0 0)
  (plug-in-exchange RUN-NONINTERACTIVE image layer2 0 0 0 255 0 0 0 0 0)
  (gimp-layer-set-mode layer1 LAYER-MODE-MULTIPLY)
  (gimp-displays-flush)
)

(script-fu-register 
  "script-fu-gimpcompare"
  "<Image>/Script-Fu/gimpcompare"
  "blue red multiply"
  "Test"
  "Test"
  "2022"
  "RGB*"
  SF-IMAGE "Image" 0
  SF-DRAWABLE "layer1" 0
  SF-DRAWABLE "layer2" 0

)
Reply
#7
(01-30-2023, 01:35 PM)salamander017 Wrote:
(01-29-2023, 09:10 PM)Ofnuts Wrote: You don't need to set active layers...  The layer argument of the (plugin-exchange) is the layer on which it will act, so this should be layer1 or layer2.

Otherwise, without changing colors, if you change the top layer to Difference blend mode, you will get white spots where the layers differ.

Oh, thank you very much for that. I have modified the code based on your suggestion. But now, when running the script, a dialog pops up and makes me choose between the layers.
But I prefer if it did not.
If I choose the top layer, only the blue to the top is applied. If I choose the bottom layer, all is applied correctly. (the top layer must be active)
When the active layer is the second layer. The colors are reversed and multiply is applied to the bottom layer instead.

(define (script-fu-gimpcompare image layer1 layer2)
  (plug-in-exchange RUN-NONINTERACTIVE image layer1 0 0 0 0 0 255 0 0 0)
  (plug-in-exchange RUN-NONINTERACTIVE image layer2 0 0 0 255 0 0 0 0 0)
  (gimp-layer-set-mode layer1 LAYER-MODE-MULTIPLY)
  (gimp-displays-flush)
)

(script-fu-register 
  "script-fu-gimpcompare"
  "<Image>/Script-Fu/gimpcompare"
  "blue red multiply"
  "Test"
  "Test"
  "2022"
  "RGB*"
  SF-IMAGE "Image" 0
  SF-DRAWABLE "layer1" 0
  SF-DRAWABLE "layer2" 0

)
I didn't say to use layers as explicit parameters to the script. Of course, when you do do, layer1 is implicitly the active layer ("drawable"(*),actually) in the image, but Gimp can't tell what layer2 should be so you get the dialog.

What I said is that (plug-in-exchange) doesn't run on the active drawable but on the drawable that you pass in its arguments.So you can take any layer of the image and give it to (plug-in-exchange) without making it active first.

So, if you remove your two SF_DRAWABLE, given just the image, you can get a list of its layers ((gimp-image_get-layers)) and then extract each of the two layers from that list and pass it to (plug-in-exchange).

(*) A "drawable" is anything you can paint on: layer, but also mask or channel. Or a layer group, on which you can't paint.
Reply
#8
(01-31-2023, 11:25 AM)Ofnuts Wrote:
(01-30-2023, 01:35 PM)salamander017 Wrote:
(01-29-2023, 09:10 PM)Ofnuts Wrote: You don't need to set active layers...  The layer argument of the (plugin-exchange) is the layer on which it will act, so this should be layer1 or layer2.

Otherwise, without changing colors, if you change the top layer to Difference blend mode, you will get white spots where the layers differ.
I didn't say to use layers as explicit parameters to the script. Of course, when you do do, layer1 is implicitly the active layer ("drawable"(*),actually) in the image, but Gimp can't tell what layer2 should be so you get the dialog.

What I said is that  (plug-in-exchange) doesn't run on the active drawable but on the drawable that you pass in its arguments.So you can take any layer of the image and give it to (plug-in-exchange) without making it active first.

So, if you remove your two SF_DRAWABLE, given just the image, you can get a list of its layers ((gimp-image_get-layers)) and then extract each of the two layers from that list and pass it to  (plug-in-exchange).

(*) A "drawable" is anything you can paint on: layer, but also mask or channel. Or a layer group, on which you can't paint.

I have updated the script, but now I get an Error: not enough arguments 
I may have wrong idea about the (gimp-image-get-layers) so please correct me

(define (script-fu-gimpcompare2 image layers layer1 layer2)
  (let*(
        (layers (gimp-image-get-layers image))
        (layer1 (car(car(cdr layers))))
        (layer2 (car(cdr(car(cdr layers)))))
       )
    (plug-in-exchange RUN-NONINTERACTIVE image layer1 0 0 0 0 0 255 0 0 0)
    (plug-in-exchange RUN-NONINTERACTIVE image layer2 0 0 0 255 0 0 0 0 0)
    (gimp-layer-set-mode layer1 LAYER-MODE-MULTIPLY)
    (gimp-displays-flush)
  )
)

(script-fu-register 
  "script-fu-gimpcompare2"
  "<Image>/Script-Fu/gimpcompare2"
  "blue red multiply"
  "Test"
  "Test"
  "2022"
  "RGB*"
  SF-IMAGE "Image" 0
)
Reply
#9
(02-01-2023, 09:35 AM)salamander017 Wrote: I have updated the script, but now I get an Error: not enough arguments 
I may have wrong idea about the (gimp-image-get-layers) so please correct me
Try reading what I wrote about setting layer1 and layer2 using aref !
Reply
#10
(02-01-2023, 09:54 AM)programmer_ceds Wrote:
(02-01-2023, 09:35 AM)salamander017 Wrote: I have updated the script, but now I get an Error: not enough arguments 
I may have wrong idea about the (gimp-image-get-layers) so please correct me
Try reading what I wrote about setting layer1 and layer2 using aref !

Sorry I forgot to mention, but I also tried this and also returned the same error: not enough arguments.
Kindly see below script. Thank you. Sorry I am still learning. 

(define (script-fu-gimpcompare3 num_layers image layers layer1 layer2)
  (let*(
        (num_layers (cad (gimp-image-get-layers image)))
        (layers (cadr (gimp-image-get-layers image)))
        (layer1 (aref layers 0))
        (layer2 (aref layers 1))
       )
    (plug-in-exchange RUN-NONINTERACTIVE image layer1 0 0 0 0 0 255 0 0 0)
    (plug-in-exchange RUN-NONINTERACTIVE image layer2 0 0 0 255 0 0 0 0 0)
    (gimp-layer-set-mode layer1 LAYER-MODE-MULTIPLY)
    (gimp-layer-set-mode layer2 LAYER-MODE-MULTIPLY)
    (gimp-displays-flush)
  )
)

(script-fu-register 
  "script-fu-gimpcompare3"
  "<Image>/Script-Fu/gimpcompare3"
  "blue red multiply"
  "Test"
  "Test"
  "2022"
  "RGB*"
  SF-IMAGE "Image" 0
)

EDIT:
OKAY I got it. I didnt need to put the variables for let inside the function. Thank you
Reply


Forum Jump: