I have a 4-channel image (RGBA). I want to reduce its channel count from 4 to 3.

The method I am using currently is to Right click and Save as a .png file. After that when I Import it in Mathematica, the channel count is reduced to 3. Is there a more elegant way to do that?

Note: RemoveAlphaChannel[] function won't work. Because that will change the appearance of the original image (see the example below).

This is a 4-channel picture from ref / AlphaChannel:

4-channel picture

 img = Import @ "https://i.stack.imgur.com/XvzDc.png"

This is the 3-channel picture which is what I want:

3-channel picture

If I use RemoveAlphaChannel[], I will get this picture instead:

Picture after RemoveAlphaChannel

  • 3
    $\begingroup$ does RemoveAlphaChannel[img, White] not work for you? it does give 3-channel image ( ImageChannels@RemoveAlphaChannel[img, White] is 3). $\endgroup$ – kglr Jan 24 at 7:26
  • $\begingroup$ @kglr Yes it works for that situation. It's amazing, thank you. $\endgroup$ – Vold Notz Jan 24 at 7:57

The second example from RemoveAlphaChannel:

  • Remove opacity by blending with a white background:

img2 = RemoveAlphaChannel[img, White]

enter image description here

ImageChannels /@ {img, img2}

{4, 3}

ColorSeparate /@ {img, img2} // Grid

enter image description here

Row[{Labeled[Framed@AlphaChannel@img, "img", Top], 
     Labeled[Framed@AlphaChannel@img2, "img2", Top]}]

enter image description here

  • $\begingroup$ Thank you very much @kglr. I wonder if RemoveAlphaChannel[#, White]& is universal. If it also works for various alpha channels. (I've tried some pictures with different alpha channels and it works, but I am still not sure whether it works for all the cases...) $\endgroup$ – Vold Notz Jan 24 at 7:54
  • $\begingroup$ @VoldikSS, I am not sure if it works for all cases. $\endgroup$ – kglr Jan 24 at 8:04

@kglr 's solution is very convenient and powerful. However RemoveAlphaChannel[#, colorname]& does not work for all the cases. So I spent some time searching in the web about image channels and found the principle of the alpha channel.

Based on that, I get the following solution which can used for other cases(different images with different alpha channels).

reduceImageChannels[img_] :=
    Map[(#*#[[4]] + 1*(1 - #[[4]])) &,
     (Flatten[ImageData@img, 1])]] // Partition[#, First@ImageDimensions[img]] & // Image

To check if it works

img = Import @ "https://i.stack.imgur.com/XvzDc.png"

enter image description here

img2 = reduceImageChannels@img

enter image description here



It given me the image exactly what I want. Exciting!

BTW, I am a mathematica newbie, so be free to correct my code and English grammer.

  • $\begingroup$ I haven't ran the code, but Most gives all but the last element of a list. And what is 120 doing there, is that something to do with the ImageDimensions? $\endgroup$ – KraZug Jan 26 at 13:42
  • $\begingroup$ Thank you for the suggestion! I will replace Drop[#, {4}] & with Most. You are right, ImageDimensions@img returns {120,120} $\endgroup$ – Vold Notz Jan 26 at 13:45
  • $\begingroup$ you can also use reduceImageChannels2[img_] := Map[Most[#*#[[4]] + 1*(1 - #[[4]])] &, ImageData@img, {2}] $\endgroup$ – kglr Jan 26 at 13:56
  • $\begingroup$ @kglr Thanks, it's much more elegant! I even forgot the Map's levelspec option... $\endgroup$ – Vold Notz Jan 26 at 13:59
  • 1
    $\begingroup$ for an arbitrary color in the second argument,say Orange, RemoveAlphaChannel[img, Orange] and ImageApply[Most[#]*#[[4]] + {1, 0.5, 0}*(1 - #[[4]]) &, img] gives the same image as ImageApply[Most[#]*#[[4]] + {1, 0.5, 0}*(1 - #[[4]]) &, img] (that is, Max@(ImageData@ ImageApply[Most[#]*#[[4]] + {1, 0.5, 0}*(1 - #[[4]]) &, img] - ImageData[RemoveAlphaChannel[img, Orange]]) .) Note that Orange is RGBColor[1,.5,0]. $\endgroup$ – kglr Jan 26 at 14:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.