4
votes

So I have a situtation with ImageMagick and php where I need to processes each of the RGB channels separately and then merge them back together into the final image. So in the code I have below, $red, $green and $blue are the channels (as gray scale images). The following code is what I have tried (and a couple variations) but each time I end up with an image that only has Cyan, Magenta or Yellow showing through. In this case, the resulting image is Cyan.

$im->removeImage();
$im->addImage($red);
$im->addImage($green);
$im->addImage($blue);
$img = $im->combineImages(self::CHANNEL_ALL);

$im->removeImage();
$im->removeImage();
$im->removeImage();
$im->addImage($img);

I think part of my problem is that the PHP documentation doesn't say much about how to use combineImages and there are no samples so far as I can find. So it's very likely that I'm using that particular method incorrectly, and I suspect it has to do with how I am combining the images in the single Imagick object to begin with.

EDIT

This question ultimately boils down to this: How do I recreate the following script using only php?

convert tmp_r.png tmp_g.png tmp_b.png -combine tmp_rgb.png
3
I have spent all evening trying to this to work and I always end up with a red or gray image. After a few hours I began to think addImage is wrong as this looks like it is for gif animations. I found a post on the Imagemagick forum suggesting compositing instead. I can not get my head around how Imagick works as the documentation is totaly useless and misleading.Bonzo
100% agree about the documentation ....gregghz
where did you find that post?gregghz
There is not very much info and it was in the rmagick section of the forum: imagemagick.org/discourse-server/… I have spent all weekend trying to create an example of all the Imagick operators to put on my website but am stuck now with the ones without very good documentation!Bonzo
Is there any particular reason you're forcing yourself to use the PHP Imagick extension rather than just using a shell command?Crontab

3 Answers

4
votes

[EDIT] I have to admit, looking further into the documentation, Im not sure what the constant CHANNEL_ALL does. They do state that you can concatenate channels by logically ORing them together. You might try:

$im->combineImages(imagick::CHANNEL_RED | imagick::CHANNEL_GREEN | imagick::CHANNEL_BLUE);

[ORIGINAL] I've been looking into this API, and honestly what I think you are looking for is the convert function, NOT the combine function.

Look At the below provided link and click specifically on "Combining RGB Channel Images" http://www.imagemagick.org/Usage/color_basics/

Try that, leave a comment if you need further help :-)

3
votes

So I think I've figured out how to get this to work. The missing piece was a call to flattenImages(). I'm not exactly sure why this worked, but it seems to be what I was looking for. Here's the code (keep in mind that $this is in the context of a member method of a class that extends Imagick):

$this->removeImage(); // gets rid of the old, unprocessed image
$rgb = clone $this;

$rgb->addImage($red);
$rgb->addImage($green);
$rgb->addImage($blue);
$rgb->flattenImages(); // this is what was missing above

$rgb = $rgb->combineImages(self::CHANNEL_ALL);

$this->addImage($rgb);

Can anyone comment on why this might be? I expected flattenImages() to merge the three images into one and destroy some of the information, but it appears that it actually tells ImageMagick to process all of the contained images together whereas it was processing them independently previously.

-1
votes

Try this:

$im->addImage($red);
$im->addImage($green);
$im->addImage($blue);
$im->combineImages(imagick::CHANNEL_RED | imagick::CHANNEL_GREEN | imagick::CHANNEL_BLUE);

btw combineImages doesn't return imagick object, but true/false indicating success or failure, so $im will contain your combined image.

Edit: Apparently combineImages sucks big time, so here's an alternative: imagick::compositeImage

$im->compositeImage($red, imagick::COMPOSITE_COPY, 0, 0, imagick::CHANNEL_RED);
$im->compositeImage($green, imagick::COMPOSITE_COPY, 0, 0, imagick::CHANNEL_GREEN);
$im->compositeImage($blue, imagick::COMPOSITE_COPY, 0, 0, imagick::CHANNEL_BLUE);