# Getting RGBA data from an image

What is going on with returned data in the following examples? It appears ImageData returns different types depending on the what data is passed into Image.

How do I force ImageData to always return the RGBA {{{0,0,0,0},{255,255,255,255}}} version of the data?

ImageData[Image[{{{0, 0, 0,0}, {255, 255, 255,255}}}, "Byte"],"Byte"]
{{{0, 0, 0,0}, {255, 255, 255,255}}}


Now if I pass a compressed form of the same image I don't get back the RGBA representation of the image, but the same compressed form.

ImageData[Image[{{0, 255}}, "Byte"], "Byte"]
{{0, 255}}


Is there a way to construct an Image that insures Mathematica always returns the RGBA form of the data? Basically I am looking for a function in the form of ConvertToRGBA[i_Image] := ...

• ImageData[ColorConvert[Image[{{0, 255}}, "Byte"], "RGB"], "Byte"]? No alpha channel, tho. – J. M.'s torpor Jun 10 '13 at 17:14
• @J. M. That works well, I just need a way to detect if the is already an Alpha before adding it like this Map[(Append[#, 255]) &,ImageData[ColorConvert[Image[{{{0, 0, 0, 0, 0}, {255, 255, 255, 255, 255}}}, "Byte"],"RGB"], "Byte"],2] – William Jun 10 '13 at 17:22
• "It appears ImageData returns different types depending on the what data is passed into Image.": No, ImageData does not return different types depending on the input image --- with the only exception of "Bit" images for which ImageData gives 0 and 1, not real values 0. and 1. – Matthias Odisio Jun 12 '13 at 19:31
• @Matthias, BTW, if you think a post could use a more informative title, feel free to (propose an) edit; just click on the "edit" button at the bottom of the question. – J. M.'s torpor Jun 12 '13 at 19:41
• @MatthiasOdisio It just depends on what "type" you are referring to: either Image[d,"type] or ImageData[d,"type"]). In M8.0 ImageData[d,"Byte"] will output RGB {255,255,255}. Sometimes it will output RGBA {255,255,255,255} if their is an Alpha channel, and then occasionally it will output {1.0,1.0,1.0}. I wouldn't be surprised if outputs other formats occasionally also. – William Jun 12 '13 at 20:25

You could use ColorSeparate and ColorCombine:

ConvertToRGBA[i_Image] := i ~ColorSeparate~ "RGBA" ~ColorCombine~ "RGB"


This function first converts to "RGB", then inquires about the presence of an alpha channel. If there is none, it adds one. Then it returns the data cast as type "Byte" by default. Casting to 8-bit unsigned values may lead to clipping and rounding, that's why it is possible to specify the type via the second optional argument. Other data loss may occur if the image has a different colorspace (say, "LAB"), or if it is a multichannel image.

ConvertToRGBA[img_, type_: "Byte"] :=
With[{image = ColorConvert[img, "RGB"]},
If[ ImageMeasurements[image, "Transparency"],
ImageData[image, type],
ImageData[SetAlphaChannel@image, type]
]
];

• Do you mind posting an example where this might be better then SimonWoods answer? I would certainly like to understand what you mean by LAB – William Jun 20 '13 at 20:42
• SimonWoods' answer is fine. It does not give the data, but just a RGB image with transparency. Make both solutions return the same result by wrapping an ImageData[#, "Byte"]& around his function, and you'll see that my code is faster. – Matthias Odisio Jun 20 '13 at 23:04
• As for your question about "LAB", I juts wanted to point out that performing the operation you are asking for (converting an image to "RGB" and to the data type "Byte") may lead to data "loss". For example, LAB colors can not be all represented as RGB colors. – Matthias Odisio Jun 20 '13 at 23:10

I prefer Simon Wood's answer, but here is a slightly different solution which appends an alpha value to each pixel after converting the image to an RGB representation.

ConvertToRGBA[i_Image] := ArrayPad[ImageData[ColorConvert[i, "RGB"], "Byte"], {0, 1}, 255]

ConvertToRGBA[Image[{{{0, 0, 0}, {255, 255, 255}}}, "Byte"]]

• You should probably check that the image doesn't already have an alpha channel. Also you will probably find ArrayPad to be faster than mapping Append onto every pixel. – Simon Woods Jun 12 '13 at 20:39
• @SimonWoods Is this what you had in mind ArrayPad[#, {0, 1}, 255] or is there way to remove the map completely? EDIT: Neverming I see what you mean ArrayPad[ImageData[ColorConvert[i, "RGB"], "Byte"], 2], {0, 1}, 255] – William Jun 12 '13 at 20:43