PNG is turning my 8-bit grayscale to RGB


I have a set of images that consist of a single channel of transparency information, with no colour (i.e. grayscale images). I want to draw the image to the screen using a particular color, where each grayscale pixel in the image is used as a transparency value to transfer the desired colour (which can itself have transparency).

At first I didn’t see the fillAlphaChannelWithCurrentBrush parameter to Graphics::drawImage. But then I saw it and realized it was exactly what I needed.

So, I load my Image using the PNG loader. In Photoshop, my PNG is an 8-bit grayscale image. But when I load it up using ImageFileFormat::loadFrom(), it comes out as RGB. This seems to be happening in juce_PNGLoader.cpp:

        if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
            png_set_gray_to_rgb (pngReadStruct);

This seems very unfriendly! I want my PNG to stay as Image::PixelFormatType::SingleChannel (I speak Juce now).

And, I want Graphics::drawImage() to treat this as the alpha channel when I pass fillAlphaChannelWithCurrentBrush=true


How is it possible to create a grayscale Image, that also has an associated alpha channel? i.e. 2 bytes per pixel? Or two planes of image data?


I guess it could load a single-channel PNG as a single-channel image… I wrote the PNG code long before the Image class supported single-channel formats. It’d probably also be handy to have a function to convert an RGB image to an alpha image by using the brightness or a particular colour channel.

That’s actually a bit of a throwback to olden days that I left in there for backwards-compatibility - it’s better to use Graphics::reduceClipRegion (const Image&) and then to draw inside it. (That’s what the fillAlphaChannelWithCurrentBrush option uses internally now anyway).

Sorry, ain’t got support for fancy doodads like that. Just plain ol’ ARGB.


Hi Jules,

It’s will be much helpful if there is a function to convert the RGB image to an alpha image. There are still much requirement to operate the bitmap in the app.




Jules I wrote a little sample program which shows the hoops I have to jump through to “tint” a grayscale PNG using the current colour in the Graphics context:

The two issues are:

  1. Grayscale PNG comes in as RGB

  2. Even after turning a PNG into a Grayscale, the Graphics won’t treat it as an Alpha channel when fillAlphaChannelWithCurrentBrush==true. I have to swizzle the bits every time I load a PNG, which kind of sucks. I wish there was a Graphics function which draws a grayscale image, treating it as an alpha channel, and using the current brush. I use this a lot in my app for controls. I draw it offset, in a shade of black, to get a drop shadow, and then draw it in the normal position with the control colour, to get a nice looking image suitable for use a button label and what not.