1
\$\begingroup\$

There have been a few questions similar to this but none seem to give a straight answer. If I am creating a Bitmap from a .png image and want to set a color (i.e. true pink) to transparent, the color turns black instead. I am using get and set pixel methods, iterating through an array of pixel colors.

The method I wish to accomplish this in is as follows:

public Bitmap getFormattedBitmap(Bitmap bm, int newHeight, int newWidth, int r, int g, int b, int a) {
int width = bm.getWidth();
int height = bm.getHeight();
int pixNum = width * height;
int[] pixels = new int[pixNum];
int scaleWidth =  newWidth * width;
int scaleHeight = newHeight * height;

bm.getPixels(pixels, 0, width, 0, 0, width, height);

for(int k = 0; k < height; k++) {
   for(int j = 0; j < width; j++ ) {
        int red   = Color.red(bm.getPixel(j, k));
        int green = Color.green(bm.getPixel(j, k));
        int blue  = Color.blue(bm.getPixel(j, k));
        int alpha = Color.alpha(bm.getPixel(j, k));
        int index = k * width + j;

        if(red == 0 && green == 0 && blue == 0 && alpha == 255) {
            pixels[index] = Color.argb(a, r, g, b);
        }
        else {
            pixels[index] = Color.argb(0, 255, 255, 255);
        }
    }
}

bm.setPixels(pixels, 0, width, 0, 0, width, height);

Bitmap resizedBitmap = Bitmap.createScaledBitmap(bm, scaleWidth, scaleHeight, true);
return resizedBitmap;

}

As you can see, I am using the Color.argb() method to set the alpha to 0, but in reality, it just shows those parts as black on the screen. I recognize bitmaps don't take kindly to alpha channels (unless you configure it to ARGB_8888), but this has me stumped. It is also interesting to note that I do have SOME control of alpha via the Color.argb() method, it is just if it is too close to 0 it turns black anyway. Something in that method or whatever I am doing does not like full transparency apparently.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Is it possible that your source bitmap might not be in the correct format? Bitmap.createScaledBitmap is going to copy the original Bitmap with respect to its original Bitmap.Config. \$\endgroup\$
    – user39686
    Commented Dec 30, 2013 at 11:59
  • \$\begingroup\$ After doing a print check, the Bitmap at that point is still ARGB_8888 format and isMutable() is true. \$\endgroup\$
    – A13X
    Commented Dec 30, 2013 at 18:05

1 Answer 1

2
\$\begingroup\$

I just love these simple methods that throw a wrench in your gears.

I perused the internet a little harder and found that I needed to add bm.setHasAlpha() before the image is reformatted, so it realizes it has alpha. I know, it seems redundant, especially since it appears to be in ARGB_8888 the entire time.

Hopefully others can learn from this, I am implementing in a game actually to change a color on my spritesheet to transparent (blitting is the term I believe). While not many phones have pre-Honeycomb anymore, it would be interesting if anyone can find a work around for < API 8.

Thanks for reading, here's the method:

public Bitmap[] loadText(String msg, int size, int red, int green, int blue, int alpha) {
    //Jumping to next line algorithm
    //Would use toUpperCase, but location problem w/upper case in other languages...
    Bitmap[] phrase = new Bitmap[msg.length()];
    for(int i = 0; i < msg.length(); i++) {
        for(int j = 0; j < characters.length(); j++) {
            if(msg.charAt(i) == characters.charAt(j)) {
                if(j <= 38) {
                    letter = Bitmap.createBitmap(Assets.textFont, j * 8, 216, 8, 8); //Subset method
                    letter.setHasAlpha(true);
                    letter = getFormattedBitmap(letter, size, size, red, green, blue, alpha);
                    phrase[i] = letter;
                }
                else {
                    letter = Bitmap.createBitmap(Assets.textFont, (j - 39) * 8, 232, 8, 8); //Subset method
                    letter.setHasAlpha(true);
                    letter = getFormattedBitmap(letter, size, size, red, green, blue, alpha);
                    phrase[i] = letter;
                }
            }
        }
    }
    return phrase;
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Spent all day banging my head against the wall about black "transparent" bitmaps until I found this. No idea how the hasAlpha is getting un-set but resetting it works like a charm. \$\endgroup\$
    – RobP
    Commented Dec 2, 2017 at 6:39
  • 1
    \$\begingroup\$ Another day saved by you sharing your findings about setHasAlpha. Thank you. \$\endgroup\$
    – Arttu
    Commented Jun 9, 2022 at 13:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .