Clip image and paste into another in one step?

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
jmaeding
Posts: 54
Joined: 2006-05-03T09:48:26-07:00

Re: Clip image and paste into another in one step?

Post by jmaeding »

ah, I did get this to work:
convert largeimage.tiff ( maskedimage.tiff -distort Perspective "{16_numbers}" ) -compose over -composite out.tiff
my code:
"C:\Program Files\ImageMagick-7.0.5-Q16\magick.exe" "C:\Temp\Orig.JPG" ( "C:\Temp\Clipped.png" -distort Affine "0,0 200,200 0,1440 400,800" ) -compose over -composite "C:\Temp\Final.jpg"

seems it needed a - before composite, which I thought I tried but must not have.
James Maeding
Civil Engineer / Programmer
jmaeding
Posts: 54
Joined: 2006-05-03T09:48:26-07:00

Re: Clip image and paste into another in one step?

Post by jmaeding »

I got it all working into one statement. The three parts were:
1) to make mask
"C:\Program Files\ImageMagick-7.0.5-Q16\magick.exe" -size 2160x1440 xc:black -fill white -stroke black -draw "polygon 447.72,217.87 232.29,702.26 964.73,1116.68 1578.69,1138.21 1917.98,449.3 1761.8,34.88 760.08,51.02 447.72,217.87" "C:\Temp\Stencil.gif"

2) to apply mask
"C:\Program Files\ImageMagick-7.0.5-Q16\magick.exe" "C:\Temp\ToPaste.JPG" "C:\Temp\Stencil.gif" -alpha off -compose copyopacity -composite "C:\Temp\Clipped.png"

3) to merge images
"C:\Program Files\ImageMagick-7.0.5-Q16\magick.exe" "C:\Temp\Orig.JPG" ( "C:\Temp\Clipped.png" -distort Affine "0,0 200,200 0,1440 400,800" ) -compose over -composite "C:\Temp\Final.jpg"

Combined gives:
"C:\Program Files\ImageMagick-7.0.5-Q16\magick.exe" "C:\Temp\Orig.JPG" ( ( "C:\Temp\ToPaste.JPG" ( -size 2160x1440 xc:black -fill white -stroke black -draw "polygon 447.72,217.87 232.29,702.26 964.73,1116.68 1578.69,1138.21 1917.98,449.3 1761.8,34.88 760.08,51.02 447.72,217.87" ) -alpha off -compose copyopacity -composite ) -distort Affine "0,0 200,200 0,1440 400,800" ) -compose over -composite "C:\Temp\Final.jpg"

"That really is truly amazing. That is so amazingly amazing I think I'd like to steal it." -Zaphod
James Maeding
Civil Engineer / Programmer
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Clip image and paste into another in one step?

Post by snibgo »

jmaeding wrote:I have not tried on the super large images yet, but am wondering if -layers merge is better or worse than just -compose, though I could not get -compose by itself to work.
"-compose" needs the minus.

"-layers merge" or "-layers flatten" is like "-composite" but will operate on any number of images, and also against the "-background" colour. So it may be slower than the equivalent "-composite", but I've not tested that. The other difference is when you want to offset images: "-layers" needs "-repage" but "-composite" needs "-geometry".


On your final command: Good stuff, and Mr Adams can always supply a suitable quote. I would divide the command into lines, something like this:

Code: Select all

"C:\Program Files\ImageMagick-7.0.5-Q16\magick.exe" ^
  "C:\Temp\Orig.JPG" ^
  ( ^
    ( "C:\Temp\ToPaste.JPG" ^
      ( -size 2160x1440 xc:black -fill white -stroke black ^
        -draw "polygon 447.72,217.87 232.29,702.26 964.73,1116.68 1578.69,1138.21 1917.98,449.3 1761.8,34.88 760.08,51.02 447.72,217.87" ^
      ) ^
      -alpha off -compose copyopacity -composite ^
    ) ^
    -distort Affine "0,0 200,200 0,1440 400,800" ^
  ) ^
  -compose over -composite ^
  "C:\Temp\Final.jpg"
From that, we can readily see that Orig.JPG is read, and then we do a load of processing to ToPaste.JPG that has no dependency on Orig.JPG. So we don't need to have Orig.JPG in memory for all that time. We can rearrange the command, simplifying slightly:

Code: Select all

"C:\Program Files\ImageMagick-7.0.5-Q16\magick.exe" ^
  ( "C:\Temp\ToPaste.JPG" ^
    ( -size 2160x1440 xc:black -fill white -stroke black ^
      -draw "polygon 447.72,217.87 232.29,702.26 964.73,1116.68 1578.69,1138.21 1917.98,449.3 1761.8,34.88 760.08,51.02 447.72,217.87" ^
    ) ^
    -alpha off -compose copyopacity -composite ^
  ) ^
  -distort Affine "0,0 200,200 0,1440 400,800" ^
  "C:\Temp\Orig.JPG" ^
  +swap ^
  -compose Over -composite ^
  "C:\Temp\Final.jpg"
(I haven't tested this. You could verify it makes the same result.)

This doesn't reduce the amount of processing, but does reduce memory requirement. (In this case, with giggles available and presumably a brain the size of a planet, that might not be important.)

Image processing is a form of engineering: alternative methods are usually available, often involving trade-offs, but sometimes one method is simply better than another.
snibgo's IM pages: im.snibgo.com
jmaeding
Posts: 54
Joined: 2006-05-03T09:48:26-07:00

Re: Clip image and paste into another in one step?

Post by jmaeding »

Thanks for the comments Snibgo!
I have had great results in terms of performance, on my largest images (30kx40k pixels). Less than 1 minute processing times and no memory issues.
I did realize, though, that I was not dealing with distort cords that rotated the paste image in my tests.
I had simple ones, or ones that stayed inside the original image pixel dims.

To keep this simple, lets say I have two IM images - granite.png and navy.png.
I want to past navy.png into granite.png where 0,0 in navy goes to 10,10 in granite,
and 0,64 in navy goes to 40,45 in granite.
I choose non-even values on purpose as I must use from-to pairs of cords in the program I am doing.

My attempt at this is:
"C:\Program Files\ImageMagick-7.0.5-Q16\magick.exe" ^
"C:\Users\james\Desktop\Kir\granite.png" ^
( "C:\Users\james\Desktop\Kir\navy.png" -alpha set -virtual-pixel transparent +distort Affine "0,0 10,10 0,64 40,45" ) ^
-background none -compose over -composite "C:\Temp\Final.jpg"

I studied the "3d Cubes, using Affine Layering" example a bunch and its seems so simple, yet I am missing something.
You use +distort to place some image onto the virtual canvas, then crop and repage at the end.
I tried like 10 variations on code above, but clearly the +distort is not placing the result where I said on the virtual canvas, or adding granite.png is not happening where I thought. Thanks for any help on this.
James Maeding
Civil Engineer / Programmer
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Clip image and paste into another in one step?

Post by fmw42 »

I have not followed this too closely, but when you use +distort and are putting one image over another, typically you use -layers merge +repage rather than -compose over -composite. If that does not help, then I will let snibgo help you further, since he has provided code for you already.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Clip image and paste into another in one step?

Post by snibgo »

Can you provide the inputs granite.png and navy.png? You can upload to anywhere such as dropbox.com and paste the URLs here.

As Fred says. I mentioned above that when offsets are used, "-composite" and "-layers merge" are different. In this example, your "+distort" has created an offset. You can see this if you insert "+write info:" immediately after it. "-composite" ignores that type of offset. "-layers merge" will take it into account.
snibgo's IM pages: im.snibgo.com
jmaeding
Posts: 54
Joined: 2006-05-03T09:48:26-07:00

Re: Clip image and paste into another in one step?

Post by jmaeding »

ok, I'm a bonehead. I used -composite instead of -layers merge...deet-tuh-deeeee
I switched, and added cropping to get:
"C:\Program Files\ImageMagick-7.0.5-Q16\magick.exe" ( ^
"C:\Users\james\Desktop\Kir\granite.png" ^
( "C:\Users\james\Desktop\Kir\navy.png" -alpha set -virtual-pixel transparent +distort Affine "0,0 10,10 0,64 40,45" ) ^
-background none -compose over -layers merge ) ^
-crop 128x128 "C:\Temp\Final.jpg"

that works. Note the parens to separate out the crop step. I wonder if a viewport could do this, maybe several ways.
Now to test in the program.
James Maeding
Civil Engineer / Programmer
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Clip image and paste into another in one step?

Post by snibgo »

jmaeding wrote:I wonder if a viewport could do this, ...
In general, viewport is quicker than cropping after the distort because it doesn't need to calculate pixels that are then discarded.
snibgo's IM pages: im.snibgo.com
jmaeding
Posts: 54
Joined: 2006-05-03T09:48:26-07:00

Re: Clip image and paste into another in one step?

Post by jmaeding »

ok, seems this works too, without cropping and the background setting too:
"C:\Program Files\ImageMagick-7.0.5-Q16\magick.exe" ( ^
"C:\Users\james\Desktop\Kir\granite.png" ^
( "C:\Users\james\Desktop\Kir\navy.png" -alpha set -virtual-pixel transparent -define distort:viewport=128x128+0+0 -filter point +distort Affine "0,0 10,10 0,64 40,45" ) ^
-compose over -layers merge ) ^
"C:\Temp\Final.jpg"
James Maeding
Civil Engineer / Programmer
Post Reply