Search code examples
pythonubuntugimpgimpfu

Gimpfu scripting: Why does layer's ID get corrupted?


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.


Solution

  • 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)