14

I have a single-channel PNG file I'd like to use as an alpha mask for Porter-Duff drawing operations. If I load it without any options, the resulting Bitmap has an RGB_565 config, i.e. treated as grayscale. If I set the preferred config to ALPHA_8, it loads it as a grayscale ARGB_8888 instead.

How can I convince Android to treat this file as an alpha mask instead of a grayscale image?

mask1 = BitmapFactory.decodeStream(pngStream);
// mask1.getConfig() is now RGB_565

BitmapFactory.Options maskOpts = new BitmapFactory.Options();
maskOpts.inPreferredConfig = Bitmap.Config.ALPHA_8;
mask2 = BitmapFactory.decodeStream(pngStream, null, maskOpts);
// mask2.getConfig() is now ARGB_8888 (the alpha channel is fully opaque)
kvance
  • 1,479
  • 18
  • 22
  • What happens when you set the preferred config to ARGB_8888? – EboMike Oct 28 '10 at 19:14
  • Same result as ALPHA_8. I get an ARGB_8888 bitmap with an opaque alpha channel. – kvance Oct 28 '10 at 19:20
  • What color type is your png? I am guessing 0, which is grayscale. As far as I know there is no "alpha only" png file. The closest you could get to that would be an 8 bit palette with an identity map of index to alpha - for file size. But probably not worth it. Your workaround below is probably the best you will get. But I hate to be that guy: The API is trying to tell you something here! Keep alpha and RGB together. Always. It's going to be faster and better supported. By using ALPHA_8 you leave the good path. Try to change your design to RGBA if at all possible. – starmole Jun 10 '13 at 07:19
  • @starmole Correct, it was a grayscale PNG. In this particular case I had large, animated sprites with an alpha channel. In terms of app size, it was well worth it to compress the RGB data with JPEG and the alpha channel with PNG. – kvance Jun 11 '13 at 13:58

1 Answers1

7

More of a workaround than a solution:

I'm now including the alpha channel in an RGBA PNG file with the RGB channels all zeroes. I can load this file with a preferred config of ARGB_8888 and then extract its alpha channel. This wastes a few KB in the mask file, and a lot of memory while decoding the image.

BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap source = BitmapFactory.decodeStream(pngStream, null, opts);
Bitmap mask = source.extractAlpha();
source.recycle();
// mask.getConfig() is now ALPHA_8
kvance
  • 1,479
  • 18
  • 22