Why is the color changed after applying ImageData?

I have an image square.png as below:-

I imported the image as ImageSquare, and then applied ImageData to the image. When I applied Image to convert the image back, the color is changed:-

ImageSquare = Import@StringJoin[NotebookDirectory[], "square.png"]
ImageSquare2 = Image@ImageData@ImageSquare


Why is that? In fact if I checked the value of the images, I still got True:

(ImageData@ImageSquare2) == (ImageData@ImageSquare)


Many thanks!!

You should specify the ColorSpace manually:

ImageSquare2 = Image[ImageData@ImageSquare, ColorSpace -> "RGB"]


Or take it from the original image:

colorSpace = Options@ImageSquare
ImageSquare2 = Image[ImageData@ImageSquare, colorSpace]


The original approach yield:

Options@(Image@ImageData@ImageSquare)
(* {ColorSpace -> Automatic, Interleaving -> True} *)


Which is wrong and uses the following rule from Image:

{c1,c2,c3,…}  channel values rendered by equally spaced hues


This happens because this PNG file has three colour channels (RGB) and an additional alpha channel (transparency).

When applying ImageData (or ColorSeparate) blindly, we simply get four channels as the result. But the information on how to interpret these (i.e. RGB + alpha) is lost. Re-combining them gives a generic 4-channel image, not an RGB one (see here one how it's displayed).

I suggest removing the alpha channel before using ImageData: RemoveAlphaChannel.

Otherwise, use ColorSpace -> "RGB" with Image or the second argument of ColorCombine when recombining the channels. The fourth channel will be interpreted as an alpha channel in this case.

You can check if an image has an alpha channel like this: https://mathematica.stackexchange.com/a/157458/12

• Thanks. I tried RemoveAlphaChannel as you suggested and it really works. But I don't understand why it matters. I noticed that MinMax@(ImageData@ImageSquare)[[All, All, 4]] is just {1,1}. Besides, why is the color-at-the-left of ImageSquare and ImageSquare2 are still the same? I also tried to change the alpha-value of ImageSquare, but that doesn't allow me to reconstruct an image that looks like ImageSquare2. – H42 Sep 2 '18 at 15:51
ImageSquare2 = Image[ImageData@ImageSquare, Options@ImageSquare]