JokerMartini
JokerMartini

Reputation: 6147

Combine RGB channels from separate images using ImageMagick

I'm trying to combine the RGB channels from 3 separate images using ImageMagick. The red channel from image01.png, blue channel from image02.png and the green channel from image03.png

Image01.png, Image02.png, Image03.png

enter image description here enter image description here enter image description here

The resulting image should look like this (left) but I'm getting this (right):

enter image description here enter image description here

This is the command I'm running....

"C:/ImageMagick/magick.exe" convert "C:/images/image01.png" "C:/images/image02.png" "C:/images/image03.png" "-background" "#ff0000" "-channel" "red,green,blue" "-combine" "C:/images/combined.png"

Do I need to somehow save out the various channels of each image separating first and then combine the images?

Upvotes: 0

Views: 1684

Answers (2)

JengaJuice
JengaJuice

Reputation: 11

Here's my best effort at a general solution.

For each image, I create a mask of how red (or green or blue) the coloring is, combine that with the alpha channel if it has one, and create a new image by using that mask as alpha channel on a solid color image (-background red -alpha shape). Then the three images are composed together.

The result will always have alpha channel, even if input images do not.

There is probably a cleaner way to write this, and I can make no guarantee of correctness. This is the limit of my magick, but at least it produces the expected output for the sample images given here.

To see each color extraction independently, you could for example add "+write red_channel.png" after "-background red -alpha shape" to write the image to a file.

convert \
\( \( image01.png -channel g -separate +channel \) \
\( image01.png -channel b -separate +channel \) \
-compose Lighten -composite \
\( image01.png -channel r -separate -negate +channel \) \
-compose Lighten -composite -negate \
\( image01.png -alpha on -channel a -separate +channel \) \
-compose Darken -composite \
-background red -alpha shape \) \
\( \( image03.png -channel r -separate +channel \) \
\( image03.png -channel b -separate +channel \) \
-compose Lighten -composite \
\( image03.png -channel g -separate -negate +channel \) \
-compose Lighten -composite -negate \
\( image03.png -alpha on -channel a -separate +channel \) \
-compose Darken -composite \
-background lime -alpha shape \) \
-compose multiply -composite \
\( \( image02.png -channel r -separate +channel \) \
\( image02.png -channel g -separate +channel \) \
-compose Lighten -composite \
\( image02.png -channel b -separate -negate +channel \) \
-compose Lighten -composite -negate \
\( image02.png -alpha on -channel a -separate +channel \) \
-compose Darken -composite \
-background blue -alpha shape \) \
-compose multiply -composite result.png

Upvotes: 1

fmw42
fmw42

Reputation: 53071

In ImageMagick, -channel does not work to select channels from multiple images.

Furthermore and more importantly, white contains red, green and blue. So the red channel of the first image will have the red dot as white and the background white as white, leaving black for the green and blue lines. Similarly in the other images. So white needs to be made black in each image. Then the channels are separated and recombined. Then black needs to be made white again.

Unix syntax:

convert \
\( image01.png -fuzz 70% -fill black -opaque white \
-channel r -separate +channel \) \
\( image02.png -fuzz 70% -fill black -opaque white \
-channel g -separate +channel \) \
\( image03.png -fuzz 70% -fill black -opaque white \
-channel b -separate +channel \) \
-set colorspace sRGB -combine \
-fuzz 20% -fill white -opaque black \
result.png

Windows Syntax:
convert.exe ^
( image01.png -fuzz 70% -fill black -opaque white ^
-channel r -separate +channel ) ^
( image02.png -fuzz 70% -fill black -opaque white ^
-channel g -separate +channel ) ^
( image03.png -fuzz 70% -fill black -opaque white ^
-channel b -separate +channel ) ^
-set colorspace sRGB -combine ^
-fuzz 20% -fill white -opaque black ^
result.png

enter image description here

The -fuzz is needed to remove the anti-aliased colors that are near white around the edges of the colored regions.

You would be much better starting with the 3 input images that have a black background rather than white. Then all the fuzz and white to black and black back to white would not be needed.

Upvotes: 1

Related Questions