简体   繁体   中英

GIMP Python, copy layer into new image and then copy part of it

For the tile processing of a game, I want to copy many layers (=images) into one new image and "extrude" each image. Meaning that I want to extend each image a pixels to the top, bottom, left and/or right.

To test this I did the following in a Python macro;

  1. create a new image
  2. copy the existing image
  3. move new pasted image to goal location
  4. copy the top part of the new image
  5. paste the top part slightly above the goal location

and here is the code

def copy_test123(image):

    orglayer = image.layers[0]

    # 1) create new image and layer
    imgNew = gimp.Image(640, 480, RGB)
    newLayer = gimp.Layer(imgNew, "copytest", 640, 480, RGBA_IMAGE, 100, NORMAL_MODE)
    imgNew.add_layer(newLayer, 1)
    
    # 2) Copy layer from original layer and paste it into a "floating" layer in the new image
    pdb.gimp_edit_copy(orglayer)
    floatingLayer = pdb.gimp_edit_paste(newLayer, TRUE)

    # determine new position
    xgoal = 120
    ygoal = 80

    # 3) Floating layer defaults to center, more to 120,80
    xOffset, yOffset = floatingLayer.offsets
    xOffset = xgoal - xOffset
    yOffset = ygoal - yOffset

    # Move the floating layer into the correct position
    pdb.gimp_layer_translate(floatingLayer, xOffset, yOffset)

    # NOW COPY THE TOP BAR (60 pixels high) FROM THE PASTED SELECTION
    ## 
    ## # 4) copy the top part of the newly added image part
    ## pdb.gimp_image_select_rectangle(imgNew, CHANNEL_OP_REPLACE, xgoal, ygoal, orglayer.width, 60)
    ## pdb.gimp_edit_copy(floatingLayer)
    ## floatselection = pdb.gimp_edit_paste(newLayer, TRUE)
    ## 
    ## # 5) move the new extra top part slightly above the image
    ## xOffset, yOffset = floatselection.offsets
    ## xOffset = xgoal - xOffset
    ## yOffset = ygoal - 60 - yOffset
    ## 
    ## # Move the floating layer into the correct position
    ## pdb.gimp_layer_translate(floatselection, xOffset, yOffset)
    
    # Create and show a new image window for our spritesheet
    gimp.Display(imgNew)
    gimp.displays_flush()

However the result is not what I expected, see screenshot below.

在此处输入图像描述

If I leave step 4 and 5 commented out, as it is in the example code, then it shows just the new image without an extra copy of the top part, as expected. But if I uncomment/activate the code for step 4 and 5 then the result is only the top part and also it's in the incorrect position, it should be slightly higher in the image.

Btw also, in the GIMP api documentation under gimp_edit_paste it says you can copy "behind" the selection and use the selection as a mask, but I don't understand what that means. Which selection, the current selection in the image where you are pasting, or selection of the part you just copied? And why would you use that as a mask?

Anyone know what I'm doing wrong here, and how I can get the expected result?

EDIT: Thanks to @xenoid for the answer, for anyone stumble on this, here is the adjusted code to get the desired result.

def copy_test123(image):

    orglayer = image.layers[0]

    # 1) create new image and layer
    imgNew = gimp.Image(640, 480, RGB)
    newLayer = gimp.Layer(imgNew, "copytest", 640, 480, RGBA_IMAGE, 100, NORMAL_MODE)
    imgNew.add_layer(newLayer, 1)
    
    # 2) Copy layer from original layer and paste it into a "floating" layer in the new image
    pdb.gimp_edit_copy(orglayer)
    floatingLayer = pdb.gimp_edit_paste(newLayer, FALSE)

    # determine new position
    xgoal = 120
    ygoal = 80

    # 3) Floating layer defaults to center, more to 120,80
    xOffset, yOffset = floatingLayer.offsets
    xOffset = xgoal - xOffset
    yOffset = ygoal - yOffset

    # Move the floating layer into the correct position
    pdb.gimp_layer_translate(floatingLayer, xOffset, yOffset)
    
    # Anchor the floating selection before making another selection
    pdb.gimp_floating_sel_anchor(floatingLayer)

    # NOW COPY THE TOP BAR (60 pixels high) FROM THE PASTED SELECTION

    # 4) copy the top part of the newly added image part
    pdb.gimp_image_select_rectangle(imgNew, CHANNEL_OP_REPLACE, xgoal, ygoal, orglayer.width, 60)
    pdb.gimp_edit_copy(newLayer)
    floatselection = pdb.gimp_edit_paste(newLayer, FALSE)

    # 5) move the new extra top part slightly above the image
    xOffset, yOffset = floatselection.offsets
    xOffset = xgoal - xOffset
    yOffset = ygoal - 60 - yOffset

    # Move the floating layer into the correct position
    pdb.gimp_layer_translate(floatselection, xOffset, yOffset)

    # Create and show a new image window for our spritesheet
    gimp.Display(imgNew)
    gimp.displays_flush()

A bit late for me to test but I think your problem is that your 2nd paste replaces the floating selection from the first paste before it has been anchored. You should anchor your floating selection ( pdb.gimp_floating_sel_anchor(floating_sel) ) before you take another cut of it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM