1

I have been experimenting with GIMP(v2.8.10) layer's manipulation, programatically with custom gimpfu plug-ins. I successfully achieved to select, rotate, scale and translate dinamically a portion of the existing layer:

Some of the code inside the plug-in:

Simplified for relevance. All these instructions work.

# I only use one layer in the probe image
layer = img.layers[0]

selection = pdb.gimp_rect_select(img, init_coords[0], init_coords[1],
                                            my_width,my_height,2,0,0)

# Copy and paste selection
pdb.gimp_edit_copy(layer)
float_layer = pdb.gimp_edit_paste(layer, 1)

# Transform floating selection step by step
float_layer = pdb.gimp_item_transform_rotate_simple(float_layer, 
                                             ROTATE_90, 1, 0, 0)
float_layer = pdb.gimp_layer_scale(float_layer, new_width,new_height, 1)
float_layer = pdb.gimp_layer_translate(float_layer, h_offset, 0)

The problem

  • If I remove the last line(gimp_layer_translate), everything else works.
  • Else, if I remove the line containing gimp_layer_scale instead, everything else works.
  • But if I try to use all these functions together, gimp_layer_translate crashes with RuntimeError

The procedure gimp-layer-translate has been called with incorrect ID for «layer» arg. Probably is trying to operate with an unexisting layer.

I don't know why it fails like this. If they work individually, why not together? I wonder.

References

I use to start from the template.py in gimpbook.com as a starting point to build the plug-ins, due to it seems to have a solid structure to enclose the code into "undo blocks". My main source of information about pdb is this website that I found on Google. Also, I found some of the procedures I needed on this question.

Also, one of my previous questions may help as a reference on how to start making custom plug-ins for gimp.

What keeps me stuck

I'm not sure if the cause is a gimp's bug or my code is wrongly implemented. Due to some of the code posted on the answer to the linked question, I am wondering if I am overkilling the available memory (after all, I didn't know that I had to destroy the objects with an specific procedure call until I found out on that answer). What happens if I don't delete them? I wonder. Will they persist in RAM until I close GIMP, or will they generate persistent files that will flood the GIMP system? Honestly, I have no idea about the consequences of ignoring this issue.

Community
  • 1
  • 1
SebasSBM
  • 860
  • 2
  • 8
  • 32

2 Answers2

2

Remove the assignment when working with the layer. Here is how you destroy the float_layer variable:

# This creates a new layer that you assign to the float_layer
float_layer = pdb.gimp_item_transform_rotate_simple(float_layer, 
                                             ROTATE_90, 1, 0, 0)
# This does not return anything at all, it works with the layer in-place.
# But you overwrite the float_layer variable anyway, destroying it.
float_layer = pdb.gimp_layer_scale(float_layer, new_width,new_height, 1)
# This does not work because float_layer is no longer referencing the layer at all
float_layer = pdb.gimp_layer_translate(float_layer, h_offset, 0)

So do this instead:

float_layer = pdb.gimp_item_transform_rotate_simple(float_layer, 
                                             ROTATE_90, 1, 0, 0)
pdb.gimp_layer_scale(float_layer, new_width,new_height, 1)
pdb.gimp_layer_translate(float_layer, h_offset, 0)
Emil Vikström
  • 90,431
  • 16
  • 141
  • 175
0

I fixed it by switching the floating_layer to a new Layer instance, before executing those two functions.

fixed_layer = gimp.Layer(img, 'float_layer', int(gh), int(gw),
                                           RGBA_IMAGE, 100, 1)

So I make the following combination:

# Transform floating selection step by step
float_layer = pdb.gimp_item_transform_rotate_simple(float_layer, 
                                             ROTATE_90, 1, 0, 0)
fixed_layer = gimp.Layer(img, 'float_layer', new_width, new_height,
                                           RGBA_IMAGE, 100, 1)
fixed_layer = pdb.gimp_layer_scale(float_layer, new_width,new_height, 1)
fixed_layer = pdb.gimp_layer_translate(float_layer, h_offset, 0)

The problem seems to be that, after executing some procedures over the layer, it becomes None (it's like if it was automatically removed from memory...). This solution allows me to execute 2 or 3 more operations... It's not a complete solution. I'll keep researching

SebasSBM
  • 860
  • 2
  • 8
  • 32
  • It sees you didn't pay enough attention on the @Emil's answer: These procedrues you are calling **do not** return a resulting layer! They transform the layer internally. Just stop prefixing your calls with `fixed_layer = ` 0 the first layer you reference at te beggining of your script remains a valid reference. – jsbueno Jan 15 '16 at 12:15
  • 1
    jsbueno, to be fair SabsSBM posted this before I posted my answer. This answer works but for the wrong reasons. – Emil Vikström Jan 15 '16 at 13:55