Merge two images / replicating Photoshop's "resize canvas"?

IMagick is a native PHP extension to create and modify images using the ImageMagick API. ImageMagick Studio LLC did not write nor does it maintain the IMagick extension, however, IMagick users are welcome to discuss the extension here.
Jack-S

Re: Merge two images / replicating Photoshop's "resize canvas"?

Post by Jack-S »

mkoppanen wrote:Seems like neither of them helps in this case. MagickSetBackgroundColor sets the background color for the whole wand and MagickSetImageBackgroundColor sets for single image (if I understood correctly).

Could this be a bug?
Well I assume it must be (on the part of MagickWand/IMagick), because ImageMagick docs clearly state that this is supported, and there are even examples showing it working, with a "skyblue" background. There is something on this page: viewtopic.php?f=1&t=9542&p=29516&hilit= ... lor#p29516, about "xc:black", no idea what it is, but perhaps it's related in some way?
mkoppanen wrote: http://imagemagick.org/api/magick-image ... mageExtent

The api does not support setting gravity so I assume that just calling rollImage and setImageExtent.
Perhaps I'm confused, but what does the IMagick extension have to do with MagickWand? Sure MagickWand doesn't support it, but why can't it be added to IMagick?
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: Merge two images / replicating Photoshop's "resize canvas"?

Post by mkoppanen »

Jack-S wrote:Perhaps I'm confused, but what does the IMagick extension have to do with MagickWand? Sure MagickWand doesn't support it, but why can't it be added to IMagick?
Imagick extension uses the MagickWand API. Basically when you call Imagick functions it is about the same as you would use the MagickWand API in most of the cases. Imagick provides the PHP bindings, gives you the ability to use ImageMagick from PHP5.

We could propably add it to Imagick but it is against our design goal which was to follow the MagickWand API as closely as possibly, using the means that PHP5 provides.
Mikko Koppanen
My blog: http://valokuva.org
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: Merge two images / replicating Photoshop's "resize canvas"?

Post by mkoppanen »

I browsed trough the API docs and noticed this function:

http://imagemagick.org/api/magick-image ... xtentImage

I tried it with C code and it seems to be doing exactly what you're after. I will add this later today or during tomorrow so you can test it.
Mikko Koppanen
My blog: http://valokuva.org
Jack-S

Re: Merge two images / replicating Photoshop's "resize canvas"?

Post by Jack-S »

mkoppanen wrote:Imagick extension uses the MagickWand API. Basically when you call Imagick functions it is about the same as you would use the MagickWand API in most of the cases. Imagick provides the PHP bindings, gives you the ability to use ImageMagick from PHP5.
Oh OK I see. I thought that MagickWand and IMagick were completely seperate. So IMagick is basically MagickWand for PHP5.
mkoppanen wrote:I tried it with C code and it seems to be doing exactly what you're after. I will add this later today or during tomorrow so you can test it.
Yes, certainly seems to, just so long as the background colour setting works with this, as it doesn't with setImageExtent. It doesn't do the gravity bit (auto calculating x and y based on a gravity constant), however I can easily add this in, I already have the code.

One other thing, is there anywhere I can get the most recent IMagick (2.0.0rc4+) windows dll for PHP 5.2.4? Pecl4win doesn't have it.
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: Merge two images / replicating Photoshop's "resize canvas"?

Post by mkoppanen »

mkoppanen wrote:I browsed trough the API docs and noticed this function:

http://imagemagick.org/api/magick-image ... xtentImage

I tried it with C code and it seems to be doing exactly what you're after. I will add this later today or during tomorrow so you can test it.
I actually implemented it already :) It does exactly what youre looking for (unless I am completely mistaken. would not be rare thou).

The format of the method is:
Imagick::extentImage( int width, int height, int x, int y )

you can get the latest CVS version by doing this:

cvs -d :pserver:cvsread@cvs.php.net/repository checkout pecl/imagick

Then cd pecl/imagick && phpize && ./configure && make install
Mikko Koppanen
My blog: http://valokuva.org
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: Merge two images / replicating Photoshop's "resize canvas"?

Post by mkoppanen »

Jack-S wrote:One other thing, is there anywhere I can get the most recent IMagick (2.0.0rc4+) windows dll for PHP 5.2.4? Pecl4win doesn't have it.
If you're using Windows check http://snaps.php.net. You should find pecl-dev 5.2 zip from there. It should contain php_imagick.dll.

extentImage should be in the next build. I have no idea when that is thou, because they seem a bit pseudo random :)
Last edited by mkoppanen on 2007-09-30T15:33:11-07:00, edited 1 time in total.
Mikko Koppanen
My blog: http://valokuva.org
Jack-S

Re: Merge two images / replicating Photoshop's "resize canvas"?

Post by Jack-S »

Fantastic. Thank you so much. Looks like I'll have to wait till tomorrow to get the latest, I'll post back to confirm it's all good when I've tested it.

Thanks again.
Jack-S

Re: Merge two images / replicating Photoshop's "resize canvas"?

Post by Jack-S »

OK, I've tested it and yes, it does exactly what I need :), however there seems to be a little bug :(.

The x and y values move the image in the opposite direction to what you'd expect. e.g., to place the image 200px from the left of the "canvas" you have to specify it as -200, and setting it to 200 will move it off the canvas.

e.g., to get a 400x400px image in the centre of an 800x800 canvas you have to do:

Code: Select all

$imagick = new Imagick('1.jpg'); // a 400x400px image
$imagick->extentImage(800, 800, -200, -200);
Other than that it's great, thank you!
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: Merge two images / replicating Photoshop's "resize canvas"?

Post by mkoppanen »

Jack-S wrote:OK, I've tested it and yes, it does exactly what I need :), however there seems to be a little bug :(.

The x and y values move the image in the opposite direction to what you'd expect. e.g., to place the image 200px from the left of the "canvas" you have to specify it as -200, and setting it to 200 will move it off the canvas.

e.g., to get a 400x400px image in the centre of an 800x800 canvas you have to do:

Code: Select all

$imagick = new Imagick('1.jpg'); // a 400x400px image
$imagick->extentImage(800, 800, -200, -200);
Other than that it's great, thank you!
I can reproduce it with this C code

Code: Select all

#include <stdio.h>
#include <wand/magick-wand.h>

int main()
{
  MagickWand *magick_wand;
  PixelWand *pixel_wand;

  magick_wand = NewMagickWand();
  pixel_wand = NewPixelWand();

  PixelSetColor( pixel_wand, "red" );

  MagickNewImage( magick_wand, 400, 400, pixel_wand );

  MagickExtentImage( magick_wand, 800, 800, -100, -100 );

  MagickWriteImage( magick_wand, "out.jpg" );

  return 0;
}
Is wonder if this intended behavior?
Mikko Koppanen
My blog: http://valokuva.org
Jack-S

Re: Merge two images / replicating Photoshop's "resize canvas"?

Post by Jack-S »

mkoppanen wrote:Is wonder if this intended behavior?
Perhaps, but I can't think why it would be. It goes against the convention of all other methods with an x and y parameter. x is always the distance right, from the left, but this is currently the distance left from the left. Personally I can't think of any reason why this would be intended.
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: Merge two images / replicating Photoshop's "resize canvas"?

Post by mkoppanen »

Jack-S wrote:
mkoppanen wrote:Is wonder if this intended behavior?
Perhaps, but I can't think why it would be. It goes against the convention of all other methods with an x and y parameter. x is always the distance right, from the left, but this is currently the distance left from the left. Personally I can't think of any reason why this would be intended.

viewtopic.php?f=6&t=9811
Mikko Koppanen
My blog: http://valokuva.org
Jack-S

Re: Merge two images / replicating Photoshop's "resize canvas"?

Post by Jack-S »

Great, hopefully we can find out if its intended.

Regardless of that, for anyone that wants it, this is my alternative version of extentImage, which takes a gravity constant rather than x and y:

Code: Select all

class My_Imagick extends Imagick
{
	public function extentGravityImage($widthB, $heightB, $gravity = Imagick::GRAVITY_CENTER)
	{
		$widthA = $this->getImageWidth();
		$heightA = $this->getImageHeight();		
		switch ($gravity) {	
			case Imagick::GRAVITY_SOUTHWEST:
			case Imagick::GRAVITY_WEST:
			case Imagick::GRAVITY_NORTHWEST:
				$x = 0;
			break;			
			case Imagick::GRAVITY_SOUTH:
			case Imagick::GRAVITY_CENTER:
			case Imagick::GRAVITY_NORTH:
				$x = floor(($widthA - $widthB) / 2);
			break;			
			case Imagick::GRAVITY_SOUTHEAST:
			case Imagick::GRAVITY_EAST:
			case Imagick::GRAVITY_NORTHEAST:
				$x = $widthA - $widthB;
			break;
			default:
				throw new ImagickException("Gravity setting '$gravity' unknown");
			break;
		}
		switch ($gravity) {
			case Imagick::GRAVITY_SOUTHWEST:
			case Imagick::GRAVITY_SOUTH:
			case Imagick::GRAVITY_SOUTHEAST:
				$y = 0;
			break;				
			case Imagick::GRAVITY_WEST:
			case Imagick::GRAVITY_CENTER:
			case Imagick::GRAVITY_EAST:
				$y = floor(($heightA - $heightB) / 2);
			break;				
			case Imagick::GRAVITY_NORTHWEST:
			case Imagick::GRAVITY_NORTH:
			case Imagick::GRAVITY_NORTHEAST:
				$y = $heightA - $heightB;
			break;
			default:
				throw new ImagickException("Gravity setting '$gravity' unknown");
			break;
		}
		return $this->extentImage($widthB, $heightB, $x, $y);
	}
}
Last edited by Jack-S on 2007-10-01T14:23:56-07:00, edited 1 time in total.
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: Merge two images / replicating Photoshop's "resize canvas"?

Post by mkoppanen »

Jack-S wrote:Regardless of that, for anyone that wants it, this is my alternative version of extentImage, which takes a gravity constant rather than x and y:

Good work, Jack! Personally I like people who don't just leave a topic hanging but post back their results so that other people can learn from that also!
Mikko Koppanen
My blog: http://valokuva.org
Post Reply