4

My code is below. It is exactly the same code as found in the solution for this question: Make certain area of bitmap transparent on touch

And as many others I am having the same problem with this code: the circle comes out black.

I am using a PNG file as my overlay, and this file does not have any transparent areas. But as soon as I add an arbitrary transparent area to the PNG in the Photoshop, the code starts working and the circle is displayed as transparent.

Apparently, there is something with the image and how its transparency is set, but I do not know what. I need to use a PNG without any transparent areas as my overlay.

any advice?

EDIT: good code must not depend on whether the overlay image has transparency or not, I am looking for a way to handle any kind of image as my overlay, be it JPG, PNG, or something else.

EDIT 2: if I use Config.ARGB_4444 when copying my bitmap, alpha channel gets created but this format reduces the image quality. There is API Bitmap.setHasAlpha() for API level 11 and above but I am using level 10 so far.


public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new TouchView(this));
    }

    class TouchView extends View {
        Bitmap bgr;
        Bitmap overlayDefault;
        Bitmap overlay;
        Paint pTouch;
        int X = 100;
        int Y = 100;
        Canvas c2;

        public TouchView(Context context) {
            super(context);
            bgr = BitmapFactory.decodeResource(
                    getResources(),
                    R.drawable.background);
            overlay = BitmapFactory.decodeResource(
                    getResources(),
                    R.drawable.foreground)
                      .copy(Config.ARGB_8888, true);
            c2 = new Canvas(overlay);
            pTouch = new Paint(Paint.ANTI_ALIAS_FLAG);
            pTouch.setXfermode(
                  new PorterDuffXfermode(Mode.SRC_OUT));
            pTouch.setColor(Color.TRANSPARENT);
        }

        @Override
        public void onDraw(Canvas canvas){
            super.onDraw(canvas);
            //draw background
            canvas.drawBitmap(bgr, 0, 0, null);
            //copy the default overlay
            // into temporary overlay and punch a hole in it                          
            //c2.drawBitmap(overlayDefault, 0, 0, null);
            c2.drawCircle(X, Y, 80, pTouch);
            //draw the overlay over the background  
            canvas.drawBitmap(overlay, 0, 0, null);
        }
    }
}
Community
  • 1
  • 1
akonsu
  • 28,824
  • 33
  • 119
  • 194
  • just guessing - maybe the program doesn't save the alpha channel (needed for transparency) when the image doesn't have transparency? and because of missing alpha channel your program doesn't work? maybe you can force the image editor to add alpha channel also when the image doesn't have transparent areas. – User Mar 27 '12 at 14:12
  • @lxx, that is what I suspect too. I am looking for a way to set alpha channel in code if it is not in the image. I am new to android and I do not know how to do it. – akonsu Mar 27 '12 at 14:16
  • Can any one answer to this? – Farrakh Javed Aug 12 '14 at 10:09

1 Answers1

2

From http://blog.uncommons.org/2011/01/12/adjusting-the-opacity-of-an-android-bitmap/

**
 * @param bitmap The source bitmap.
 * @param opacity a value between 0 (completely transparent) and 255 (completely opaque).
 * @return The opacity-adjusted bitmap.  If the source bitmap is mutable it will be
 * adjusted and returned, otherwise a new bitmap is created.
 */
private Bitmap adjustOpacity(Bitmap bitmap, int opacity)
{
    Bitmap mutableBitmap = bitmap.isMutable()
                           ? bitmap
                           : bitmap.copy(Bitmap.Config.ARGB_8888, true);
    Canvas canvas = new Canvas(mutableBitmap);
    int colour = (opacity & 0xFF) << 24;
    canvas.drawColor(colour, PorterDuff.Mode.DST_IN);
    return mutableBitmap;
}

Note that the Bitmap.Config documentation for ARGB_4444 says:

This field was deprecated in API level 13. Because of the poor quality of this configuration, it is advised to use ARGB_8888 instead.

GreyBeardedGeek
  • 29,460
  • 2
  • 47
  • 67