offsetting the image but using its center point

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?".
rs13
Posts: 65
Joined: 2009-01-15T12:57:26-07:00

Re: offsetting the image but using its center point

Post by rs13 »

Yes, your server side script example should be fine. I was just trying to see if there is a shorter (command line) version of it.

I will test your script example and get back to you. Again, thank you for your help.

Anthony, anything to add in regards using the page and repage to solve this??
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: offsetting the image but using its center point

Post by fmw42 »

Bonzo,

I don't think your code will work as is. The flaw in your code, in my view, is that you are resizing (and shearing) the logo AFTER you get its size and compute the offset. I think one has to resize (and shear) the logo, then get the offsets for that version of the logo, since it needs to know the w and h of the resized (and sheared) logo to work properly, if I understand what you have done and what he wants.

Fred
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: offsetting the image but using its center point

Post by Bonzo »

You are correct Fred - I origanly based it on your code then changed it to Richards :?

So an extra step is required:

Code: Select all

<?php
$logo = "finished.png";
$background = "yorkshire.JPG";

exec("convert $logo -resize 80 -background none -shear 10x05 temp.png");

// Using Imagemagick or you could use getimagesize()
$offsetx = exec("convert temp.png -format \"%[fx:$xoffset-w/2]\" info:");
$offsety = exec("convert temp.png -format \"%[fx:$yoffset-h/2]\" info:");

// Comment out or remove next two lines when happy with the code
echo "Offset x = $offsetx <br>";
echo "Offset y = $offsety <br>";

exec("convert $background temp.png -geometry +{$offsetx}+{$offsety} -composite result.png");

// Comment out or remove next two lines when happy with the code
echo "<img src=\"result.png\">";

// Either unlink temp.png, leave to be overwitten next time or save it to the tempory folder in the first place for php to tidy up.
?>
rs13
Posts: 65
Joined: 2009-01-15T12:57:26-07:00

Re: offsetting the image but using its center point

Post by rs13 »

Thank you guys, this is very helpful. I will retest and confirm.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: offsetting the image but using its center point

Post by anthony »

rs13 wrote:Thank you all for your prompt responses.

Anthony, you are correct, I have a specific point in the destination image (image B) in mind and it is not the center point.

Also, I am doing the positioning of image A onto the destination image (image B) on the fly so I will not know A's dimensions which will be changing constantly.

All I need to do is to position center pixel of image A onto specific offset in the image B.

Any ideas?
Assuming that you are wanting B on top of A and the 'handle point' in B is 12,13
then you can do the following.
convert A.png -set page '-%[fx:int(w/2)]-%[fx:int(h/2)]' \
-page -12-13 B.png \
-background none -layers merge +repage \
result.png

The -set page sets the virtual offset so the center of the image A is at 0,0.
The -page then sets the page of the following image read/create so that B's handle is a 0,0 -layers merge then overlays A on a canvas, then B onto that with the given offsets while handling 'negative' offsets appropriately. Finally +repage removes the negative offset from the result.

NOTE this assumes that B is completely inside A's bounds. If this may not be that case then you may need to use -set to first save A's starting dimensions or center so you can restore the results.

This only does integer positions. If you want sub-pixel positions you will need to use distort SRT for positioning, and that can take FX escapes directly!

ASIDE: while -set page works, -set geometry does not seem to work!


Aside... THIS FAILS!!!!!

Here is a another variation of doing the math, But reading both images in first (easier scripting) and using a globle artifact which is then assigne to just one one. In this case only the overlay (B) is moved, so flatten can be used to limit output to just the first image area.

convert A.png B.png -set option:myoffset '+%[fx:int(u.w/2)-12]+%[fx:int(u.h/2)-13]' \
\( +clone -set page '%[myoffset]' \) +swap +delete \
-background none -flatten result.png

THIS FAILS!!!!! Because of the way -set does not have access to ALL the images. That is the u.h is not from A, but from the last image the expression is applied to B so the center offset saved into the global variable is B, not A
This is a bug! Arrggghhhh....
Set really needs access to all images. But to do that it will need to be removed from "mogrify"
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
rs13
Posts: 65
Joined: 2009-01-15T12:57:26-07:00

Re: offsetting the image but using its center point

Post by rs13 »

Thanks Anthony and sorry for the delay, I was traveling.

So basically all of your examples of doing it inline in the command failed, right?

I tried what Bonzo recommended using the php script and it seems to work except when the calculated offset is negative then you get +{$offsetx}+{$offsety} to become +-23+-49 which results in the warning but imageMagick still seems to process it irrespectively.

It just feels like being able to offset with center point of the image instead of north-west point would be such a common request that it would become one of the ImageMagick's option for the 'geometry' directive.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: offsetting the image but using its center point

Post by fmw42 »

I tried what Bonzo recommended using the php script and it seems to work except when the calculated offset is negative then you get +{$offsetx}+{$offsety} to become +-23+-49 which results in the warning but imageMagick still seems to process it irrespectively.
Change +{$offsetx}+{$offsety} to {$offsetx}{$offsety}

That way it won't try to add + to a - and will just take the sign included in each of {$offsetx} {$offsety}
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: offsetting the image but using its center point

Post by anthony »

rs13 wrote:except when the calculated offset is negative then you get +{$offsetx}+{$offsety} to become +-23+-49 which results in the warning but imageMagick still seems to process it irrespectively.
The IM 'geomerty argument' parser is very complex, but does allow you to use a +-X value offset.
The main problem is the the output from the %[fx:...] expression does not currently permit a 'formating' specification to define the number format (probably as a printf escape specification. Also the %[fx:...] expressions do not have access to the normal properities/artifact values, or to the other percent escapes that generate data such as color counts, unless it was specifically built into the fx expression (such as 'mean'). This can be a bit of a pain.

Essentially the percent escapes and fx expressions are two completely separate systems (one for string inclusion the other for numbers). they have only been tweeked and hacked to work roughly together. Both should be merged into a better unified system (perhaps using some other 'simple' language API inclusion).

You can offset from the center point, but only using -geometry/-composite , BUT it does not appear that you can use -set with geometry. That means you can not (currently) use percent escapes and the FX expression escape.

The other problem is the -set only has access to the individual image it is working with, making less than useful for assigning a global variable. In the globle (option: artifact set mode) the artifact gets re-assigned once for every image in sequence, so only the last image takes hold. :-(

Reminder
property - setting for individual images
artifact - setting 'option:' or -define, assigned to ALL images, generally for special operational controls.
See Basics, Set and Define
http://www.imagemagick.org/Usage/basics/#set
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
rs13
Posts: 65
Joined: 2009-01-15T12:57:26-07:00

Re: offsetting the image but using its center point

Post by rs13 »

Thank you all. I ended up using Bonzo's recommendation. As a result it is working as a php script but does what I intended. Hopefully using the center point of the placed image for the offset (as oppose to north west one) will eventually be built in -- is there anywhere I can post it as a feature request?
Post Reply