Transparency and compositing images

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.
Post Reply
Billy

Transparency and compositing images

Post by Billy »

I just started using imagemagick, and I'm trying to do something that should be simple. I want to lay a bunch of images on top of eachother, creating one image.

The problem I'm having is:

1) How do I actually combine the images correctly? Which constant / compositing mode should I choose? COMPOSITE_MULTIPLY seems to be the only one that comes close to the correct behavior, but it doesn't allow me to put an image under the other

In my example code below, when I combine "hair_back" and then the base image, the hair ends up on top of the base

I just want it to behave "normally": the way it would behave if you opened any modern image program, took one image and copied+pasted it on top of another

(please don't suggest alternative solutions such as Imagick::combineImages() because I plan to do other things once I get past this hurdle, such as changing the color of an image before it's composited on top of another)

2) How do I get transparency in my output image?. I want to output 8-bit .pngs with transparency (not the alpha channel kind). Currently it has a white background..... which isn't surprising, but, I don't know how to use a transparent "canvas" or change the white to transparency at the end

Code: Select all

header('Content-type: image/png');

$im_base = new Imagick('buildpieces/body_default.svg');
$im_base->scaleImage(160,0);

$canvas = new Imagick();
$canvas->newImage($im_base->getImageWidth(), $im_base->getImageHeight(), "white");

$im['hair_front'] = new Imagick('buildpieces/hair_front.svg');
$im['hair_back'] = new Imagick('buildpieces/hair_back.svg');
$im['glasses'] = new Imagick('buildpieces/glasses.svg');


foreach ($im as &$image) {
	$image->scaleImage(160,0);
}

$canvas->compositeImage($im['hair_back'], imagick::COMPOSITE_MULTIPLY, 0, 0);
$canvas->compositeImage($im_base, imagick::COMPOSITE_MULTIPLY, 0, 0);
$canvas->compositeImage($im['glasses'], imagick::COMPOSITE_MULTIPLY, 0, 0);
$canvas->compositeImage($im['hair_front'], imagick::COMPOSITE_MULTIPLY, 0, 0);

$canvas->setImageFormat('png');
$canvas->setCompressionQuality(90);

echo $canvas;
Billy

Re: Transparency and compositing images

Post by Billy »

So the solution seems to revolve around setImageMatte

Except that method doesn't exist!

Is it usuable in PHP? Does it go by a different name? Is it actually completely absent?

Is anyone alive out there? Does anybody actually know how to both use ImageMagick and code PHP?
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: Transparency and compositing images

Post by mkoppanen »

Hello,

setImageMatte exists if ImageMagick version higher than 6.2.8 is used. If you want to composite images on to one image use imagick::COMPOSITE_OVER
Mikko Koppanen
My blog: http://valokuva.org
Billy

Re: Transparency and compositing images

Post by Billy »

I have installed the new version now, and am able to use the function without an error message, but it still doesn't seem to do anything.

does it work with SVG? It doesn't actually have a background color, so I don't see why transparency should be difficult. Nonetheless, it gives the loaded SVG image a background of white and refuses with respect any sort of transparency. I've tried pretty much every possibility I can come up with. I removed the resizing, I set the resolution just for completeness, I tried setImageMatteColor("white"), I tried all of the above with most of the COMPOSITE_ constants, but none of these seems to work.

In the below code, for example, you see the shape on a white background rather than a blue one:

Code: Select all

header('Content-type: image/png');

$im_base = new Imagick();
$im_base->setResolution(72,72);
$im_base->readImage('buildpieces/standard.svg');
$im_base->setImageMatte(true);

$canvas = new Imagick();
$canvas->newImage($im_base->getImageWidth(), $im_base->getImageHeight(), "blue");

$canvas->compositeImage($im_base, imagick::COMPOSITE_OVER, 0, 0);

$canvas->setImageFormat('png');
$canvas->setCompressionQuality(90);

echo $canvas;
mkoppanen
Posts: 309
Joined: 2007-06-09T07:06:32-07:00

Re: Transparency and compositing images

Post by mkoppanen »

Try this

Code: Select all

header('Content-type: image/png');

$im_base = new Imagick();
$im_base->setResolution(72,72);
$im_base->setBackgroundColor("transparent");
$im_base->readImage('buildpieces/standard.svg');

$canvas = new Imagick();
$canvas->newImage($im_base->getImageWidth(), $im_base->getImageHeight(), "blue");

$canvas->compositeImage($im_base, imagick::COMPOSITE_OVER, 0, 0);

$canvas->setImageFormat('png');
$canvas->setCompressionQuality(90);

echo $canvas;
Or this:

Code: Select all

header('Content-type: image/png');

$im_base = new Imagick();
$im_base->setResolution(72,72);
$im_base->readImage('buildpieces/standard.svg');
$im_base->setImageBackgroundColor("transparent");

$canvas = new Imagick();
$canvas->newImage($im_base->getImageWidth(), $im_base->getImageHeight(), "blue");

$canvas->compositeImage($im_base, imagick::COMPOSITE_OVER, 0, 0);

$canvas->setImageFormat('png');
$canvas->setCompressionQuality(90);

echo $canvas;
Mikko Koppanen
My blog: http://valokuva.org
Post Reply