5
$\begingroup$

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] := ...

$\endgroup$
7
  • 1
    $\begingroup$ ImageData[ColorConvert[Image[{{0, 255}}, "Byte"], "RGB"], "Byte"]? No alpha channel, tho. $\endgroup$ Jun 10, 2013 at 17:14
  • $\begingroup$ @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] $\endgroup$
    – William
    Jun 10, 2013 at 17:22
  • $\begingroup$ "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. $\endgroup$ Jun 12, 2013 at 19:31
  • $\begingroup$ @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. $\endgroup$ Jun 12, 2013 at 19:41
  • $\begingroup$ @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. $\endgroup$
    – William
    Jun 12, 2013 at 20:25

3 Answers 3

6
$\begingroup$

You could use ColorSeparate and ColorCombine:

ConvertToRGBA[i_Image] := i ~ColorSeparate~ "RGBA" ~ColorCombine~ "RGB"
$\endgroup$
0
4
$\begingroup$

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]
        ]
    ];
$\endgroup$
3
  • $\begingroup$ 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 $\endgroup$
    – William
    Jun 20, 2013 at 20:42
  • $\begingroup$ 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. $\endgroup$ Jun 20, 2013 at 23:04
  • 1
    $\begingroup$ 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. $\endgroup$ Jun 20, 2013 at 23:10
2
$\begingroup$

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"]]
$\endgroup$
2
  • $\begingroup$ 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. $\endgroup$ Jun 12, 2013 at 20:39
  • $\begingroup$ @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] $\endgroup$
    – William
    Jun 12, 2013 at 20:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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