RSS/Atom feed Twitter
Site is read-only, email is disabled

Script-fu: copy an image into a different image

This discussion is connected to the gimp-user-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.

This is a read-only list on gimpusers.com so this discussion thread is read-only, too.

5 of 6 messages available
Toggle history

Please log in to manage your subscriptions.

200208151119.18114.volker.l... 07 Oct 20:15
  Script-fu: copy an image into a different image Volker Lenhardt 15 Aug 12:15
   Script-fu: copy an image into a different image Joel 15 Aug 13:59
    Script-fu: copy an image into a different image Volker Lenhardt 15 Aug 21:37
     Script-fu: copy an image into a different image Joel 16 Aug 08:31
      Script-fu: copy an image into a different image Volker Lenhardt 16 Aug 17:51
Volker Lenhardt
2002-08-15 12:15:00 UTC (over 21 years ago)

Script-fu: copy an image into a different image

Hi,

I'm a script-fu newby and I'm trying to write a script to let up to four pictures be printed on one sheet (DINA4). User selects the files and the border width. The rest is up to the script.

The new image for the sheet is established easily. So I started with the first file. I managed to open it and scale it down to a quarter of the sheet.

But I cannot find the procedures proper to copy the visible parts of the image (as one layer?) to the sheet image. Please help me.

Thanks in advance. Volker

Joel
2002-08-15 13:59:00 UTC (over 21 years ago)

Script-fu: copy an image into a different image

To copy the visible parts of the image, use these pdb functions:

gimp_image_merge_visible_layers # combine layers in original file gimp_rect_select # create a selection (in original) gimp_edit_copy # copy original to clipboard gimp_edit_paste # paste it as a new floating layer

Exact parameters, and a bit of documentation, are in the PDB. (/Xtns/DB Browser ...)

Note that if you just select, then copy, and then paste, Gimp will put the floating layer in the center of the new document. Use the gimp_layer_translate function to move it to where you want it to go. In Python (not sure what the equivalent is in Scheme), I use this code to find the physical dimensions of the stuff I want to copy, taking transparency into consideration:

pdb.gimp_selection_layer_alpha(originalFile.layers[0]) empty, x1, y1, x2, y2 = pdb.gimp_selection_bounds(originalFile)

Then, using that, I'll calculate the top/right position :

x = (x1 + x2 - originalFile.width) / 2 y = (y1 + y2 - originalFile.width) / 2

# Now, adjust for the position where the old image should be put into the # new image
x = x + top # top and left are values that I pass in y = y + left

pdb.gimp_layer_translate(floatLayer, x, y)

Good luck!

--Joel

On Thursday 15 August 2002 12:15 am, Volker Lenhardt wrote:

Hi,

I'm a script-fu newby and I'm trying to write a script to let up to four pictures be printed on one sheet (DINA4). User selects the files and the border width. The rest is up to the script.

The new image for the sheet is established easily. So I started with the first file. I managed to open it and scale it down to a quarter of the sheet.

But I cannot find the procedures proper to copy the visible parts of the image (as one layer?) to the sheet image. Please help me.

Thanks in advance. Volker

Volker Lenhardt
2002-08-15 21:37:44 UTC (over 21 years ago)

Script-fu: copy an image into a different image

Am Donnerstag, 15. August 2002 13:59 schrieb Joel:

To copy the visible parts of the image, use these pdb functions:

gimp_image_merge_visible_layers # combine layers in original file gimp_rect_select # create a selection (in original) gimp_edit_copy # copy original to clipboard gimp_edit_paste # paste it as a new floating layer

Exact parameters, and a bit of documentation, are in the PDB. (/Xtns/DB Browser ...)

That's exactly what I thought. But it doesn't seem to work. If you don't mind, I'll give you my code so far (no loop for the next three pics yet):

(define (mm-to-pixel mm xy) (if (= xy 0)
(+ (* (/ mm 25.4) (car (gimp-get-monitor-resolution))) 0.5) (+ (* (/ mm 25.4) (cadr (gimp-get-monitor-resolution))) 0.5) )
)
(define (script-fu-dina4-4 sheet-border-mm path-1) (let*(
(din-a4-x (mm-to-pixel 297 0))
(din-a4-y (mm-to-pixel 210 1))
(sheet-width (- din-a4-x (* (mm-to-pixel sheet-border-mm 0) 2))) (sheet-height (- din-a4-y (* (mm-to-pixel sheet-border-mm 1) 2))) (sheet-ratio (/ sheet-width sheet-height)) (sheet (car (gimp-image-new sheet-width sheet-height RGB))) (pic-1 (car (gimp-file-load 1 path-1 path-1))) (pic-width (car (gimp-image-width pic-1))) (pic-height (car (gimp-image-height pic-1))) (pic-ratio (/ pic-width pic-height)) ;next 2 lines: minus 2 pixel for a small white line between the four pictures (new-pic-width (- (/ sheet-width 2) 2)) (new-pic-height (- (/ sheet-height 2) 2)) (layer-1 (car (gimp-layer-new sheet new-pic-width new-pic-height 0 "Up-left" 100 0)))
)
; if the picture is portrait, it must be made landscape: (if (< pic-ratio 1.0)
(begin
(plug-in-rotate 0 pic-1 pic-1 3 TRUE) (set! pic-width (car (gimp-image-width pic-1))) (set! pic-height (car (gimp-image-height pic-1))) (set! pic-ratio (/ pic-width pic-height)) )
)
; the picture must fit either high or wide, depending on its ratio: (if (< pic-ratio sheet-ratio)
(set! new-pic-width (* new-pic-height pic-ratio)) (set! new-pic-height (/ new-pic-width pic-ratio)) )
(gimp-image-scale pic-1 new-pic-width new-pic-height) (if (> (car (gimp-image-get-layers pic-1)) 1) (gimp-image-merge-visible-layers pic-1 1) )
(gimp-image-add-layer sheet layer-1 0) (gimp-rect-select pic-1 0 0 new-pic-width new-pic-height 0 FALSE 0) (gimp-edit-copy (car (gimp-image-get-selection pic-1))) (gimp-edit-paste layer-1 0)
(gimp-display-new sheet)
; testing just to see the scaling:
(gimp-display-new pic-1)
(gimp-image-clean-all sheet)
(gimp-image-clean-all pic-1)
)
)
(script-fu-register "script-fu-dina4-4" "/Xtns/Script-Fu/VierLaden"
"Erzeugt eine DINA4-Seite mit 4 Bildern zur Druckausgabe" "Volker Lenhardt"
"GNU, Volker Lenhardt"
"12. August 2002"
""
SF-VALUE "Seitenrand (mm)" "10"
SF-FILENAME "Datei" "/bilder/"
)

If you try it out you'll find that the selection in pic-1 isn't in the edit-buffer, there's a white area instead.

What is wrong with my script?

Note that if you just select, then copy, and then paste, Gimp will put the floating layer in the center of the new document. Use the gimp_layer_translate function to move it to where you want it to go. In Python (not sure what the equivalent is in Scheme), I use this code to find the physical dimensions of the stuff I want to copy, taking transparency into consideration:

As I define a layer in "sheet" with exactly the wanted dimensions there's no need for me to change the default middle position. Sure I have to position the next three layers to their quarters.

pdb.gimp_selection_layer_alpha(originalFile.layers[0]) empty, x1, y1, x2, y2 = pdb.gimp_selection_bounds(originalFile)

Then, using that, I'll calculate the top/right position :

x = (x1 + x2 - originalFile.width) / 2 y = (y1 + y2 - originalFile.width) / 2

# Now, adjust for the position where the old image should be put into the # new image
x = x + top # top and left are values that I pass in y = y + left

pdb.gimp_layer_translate(floatLayer, x, y)

I'm very curious. Greetings from Volker

Joel
2002-08-16 08:31:41 UTC (over 21 years ago)

Script-fu: copy an image into a different image

To get it to work, I rewrote a little bit of your script. You had this:

(gimp-image-scale pic-1 new-pic-width new-pic-height) (if (> (car (gimp-image-get-layers pic-1)) 1) (gimp-image-merge-visible-layers pic-1 1) )
(gimp-image-add-layer sheet layer-1 0) (gimp-rect-select pic-1 0 0 new-pic-width new-pic-height 0 FALSE 0) (gimp-edit-copy (car (gimp-image-get-selection pic-1))) (gimp-edit-paste layer-1 0)
(gimp-display-new sheet)

I've replaced this section with:

(gimp-image-scale pic-1 new-pic-width new-pic-height) (set! merged-layer (gimp-image-merge-visible-layers pic-1 1)) (gimp-rect-select pic-1 0 0 new-pic-width new-pic-height 0 FALSE 0) (gimp-edit-copy (car merged-layer)) (gimp-image-add-layer sheet layer-1 0) (gimp-edit-clear layer-1) (gimp-edit-paste layer-1 0) (gimp-display-new sheet)

The changes are:

1. Always merging the layers. This enables us to set a variable (merged-layer) to the resulting layer, so we don't have to figure out what it is later.

2. Copying from the layer, rather than the selection. Gimp was expecting a drawable; the selection is a drawable, but internally, it's done as a channel. In this case, since everything was selected, everything would be represented as a white pixel in the channel (white=selected, black=not selected, grey=feathering/anti-aliasing). So, when you copied the selection channel, you just copied those white pixels. If you copy from the layer instead, it will get the actual contents of the selection.

3. Clearing layer-1 before putting anything on it. Otherwise, it will be filled with garbage by default.

I also moved a couple of lines around a little bit, but it's not necessary. I just did it so that I could see similar things next to each other. I know, I know.... a foolish consistency is the hobgoblin of little minds. ;-)

I'm very curious. Greetings from Volker

Glad to help!

--Joel

Volker Lenhardt
2002-08-16 17:51:35 UTC (over 21 years ago)

Script-fu: copy an image into a different image

Hi Joel,

many thanks for your help. It works. It was the mistake to copy from the selection.

Am Freitag, 16. August 2002 08:31 schrieb Joel:

I've replaced this section with:

(gimp-image-scale pic-1 new-pic-width new-pic-height) (set! merged-layer (gimp-image-merge-visible-layers pic-1 1)) (gimp-rect-select pic-1 0 0 new-pic-width new-pic-height 0 FALSE 0) (gimp-edit-copy (car merged-layer)) (gimp-image-add-layer sheet layer-1 0) (gimp-edit-clear layer-1) (gimp-edit-paste layer-1 0) (gimp-display-new sheet)

The changes are:

1. Always merging the layers. This enables us to set a variable (merged-layer) to the resulting layer, so we don't have to figure out what it is later.

Here my Gimp version (1.2.3 Linux) fails to merge layers if there's only one. It returns an error. So I put:

(if (> (car (gimp-image-get-layers pic-1)) 1) (set! pic-layer (car (gimp-image-merge-visible-layers pic-1 1))) (set! pic-layer (car (gimp-image-get-active-layer pic-1))))

2. Copying from the layer, rather than the selection. Gimp was expecting a drawable; the selection is a drawable, but internally, it's done as a channel. In this case, since everything was selected, everything would be represented as a white pixel in the channel (white=selected, black=not selected, grey=feathering/anti-aliasing). So, when you copied the selection channel, you just copied those white pixels. If you copy from the layer instead, it will get the actual contents of the selection.

3. Clearing layer-1 before putting anything on it. Otherwise, it will be filled with garbage by default.

I also moved a couple of lines around a little bit, but it's not necessary. I just did it so that I could see similar things next to each other. I know, I know.... a foolish consistency is the hobgoblin of little minds. ;-)

I'm always glad to get some good advice.

Now I can get along further with my script. There may be a time that I need more help. Till then

Thanks and greetings from Volker