# Can ImageMagick do channel difference and swap?

In emulating Kodak Infrared Ektachrome (EIR) film (a.k.a. Aerochrome) with images from a full-spectrum-modified digital camera, I want to subtract the blue channel from the red and green channel, then re-map the blue channel to red, red to green, and green to blue. (This is called "IRG to RBG transform".)

Digital infrared enthusiasts typically do this via the Photoshop "channel mixer," but that is tedious and slow in a GUI. I'd like to batch-process it.

Is this the sort of thing ImageMagick can do?

If so, can you provide a lead as to how it would be accomplished? It is not obvious from the documentation — I can see how to swap colour channels around, but not how to subtract one channel from another.

If not, is there some other open-source command-line program that could do this?

Thank you for any leads offered!

• Not familiar with the advanced imagemagick commands, but here I found someone who subtracts a number from the red channel only. Perhaps it can be expanded to subtract a channel? Commented Dec 12, 2022 at 17:57
• Interesting… they are subtracting a single scalar quantity from all the values in one channel, whereas I want to subtract one channel from another. I'll go play with it a while. Commented Dec 12, 2022 at 22:18

Check out the -color-matrix operator to see if it meets your needs.

From your description, I think the following RGB matrix transform will work:

 0  0  1   (R =  B)
1  0 -1   (G =  R - B)
0  1 -1   (B =  G - B)


But from the graphic in your post, it looks like the following RGB matrix transform is what you're after:

0    0     1      (R = B)
0.8  0    -0.8    (G = 0.8*R - 0.8*B = 0.8 * (R - B))
0    0.96 -0.96   (B = 0.96*G - 0.96*B = 0.96 * (G - B))


So your command would look like (using the 2nd matrix, for example):

magick <input_file> -color-matrix  0    0     1
0.8 -0.8   0
0    0.96 -0.96  <output_file>


Note that color channels are non-negative. Because you are subtracting channels, you might need to make sure your resulting values are non-negative as well, by adding a constant offset for the channels that had subtraction. The color matrix can accommodate 3 additional columns: 'Black', 'Alpha', and Constant, in that order. I assume your Black and Alpha channels are zero. In order to specify Constant, you have to specify '0' for Black and Alpha. So the final matrix might look like:

0    0     1     0  0  0     (R = B)
0.8  0    -0.8   0  0  0.8   (G = 0.8R - 0.8B + 0.8)
0    0.96 -0.96  0  0  0.96  (B = 0.96G - 0.96B + 0.96)


You'll have to experiment to see if you need to specify the constant value.

• Thanks. This is doing… "interesting" things with my test image. Did you figure this out by reading the source code, or do you have better documentation than the one paragraph given at imagemagick.org/script/command-line-options.php?#color-matrix ? Commented Dec 13, 2022 at 1:26
• No, I used the documentation I linked to at the beginning of my answer.
– scottbb
Commented Dec 13, 2022 at 10:14
• I've seen you mention "IRG to RGB transform" in this post and another one (or two?). I've searched, and haven't found anything specific that makes it sound like a standard colorspace matrix transform. I did find this description, "JPEG Images on SkyServer", which is a lot more involved than the matrix transform implied in the graphic in your question. Is the SkyServer description the "IRG to RGB transform" you're talking about?
– scottbb
Commented Dec 13, 2022 at 18:45
• It appears that the link you provided does have an "IRG —> RBG transform" involved. They don't seem to go into much detail on that aspect of it, though. The diagram at the top of my question shows the logic. The constants (including per-channel gamma correction, not shown) seem to be the bits that require fine-tuning. Commented Dec 13, 2022 at 19:32
• "No, I used the documentation I linked to at the beginning of my answer." Wow, you're good! That terse paragraph didn't do much for me. Commented Dec 13, 2022 at 19:33