PNG is turning my 8-bit grayscale to RGB


#1

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


#2

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?


#3

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.


#4

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.

Br

Warren


#5

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:

http://rawmaterialsoftware.com/viewtopic.php?f=2&t=6583

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.