This took me a lot longer to figure out than it should have done. I’m documenting it here in case it’s useful for somebody else searching for a similar solution.
If you’re displaying the Bitmap
in an ImageView
, you can probably use the ImageView.setAlpha(int)
method. However, if the ImageView
is accesed via RemoteViews
, as is the case when updating a widget, you won’t be able to invoke this method (if you try to call it via RemoteViews.setInt(int, String, int)
you’ll get an exception telling you as much).
After much searching I was unable to find a widget-friendly mechanism for adjusting an ImageView
‘s transparency, or any obvious way of manipulating a Bitmap
‘s alpha channel.
Eventually I stumbled upon Kevin Dion’s excellent answer to a different but related question on StackOverflow. From this I was able to figure out that I needed to use the DST_IN
Porter-Duff mode to modify the alpha channel.
/** * @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; } |
Addendum (13 February 2013): Balazs Balazs e-mailed me to point out the following:
This might not work if the original bitmap is mutable but is not created with a config
Bitmap.Config.ARGB_8888
.For example Samsung Galaxy S2 by default returns a mutable bitmap from
BitmapFactory.decodeResource
with a config ofRGB565
.So it would be safer to leave out the
bitmap.isMutable()
check and always copy the bitmap.