I've recently noticed these exceptions (that are caught but logged in logcat):
W/System.err( 2612): java.lang.RuntimeException: Canvas: trying to use a non-premultiplied bitmap android.graphics.Bitmap@535924e0
W/System.err( 2612): at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1088)
W/System.err( 2612): at android.graphics.Canvas.<init>(Canvas.java:139)
System.err( 2612): at com.example.imaging.ImageHelper.addShadow(ImageHelper.java:553)
I've tried understanding what this exception means (as well as non-premultiplied bitmaps), but I'm not sure what could be causing this exception. Is the problem with the images we're getting from the server or is it something we're doing locally? (It's not just this line that causes the exception, but it's one of them).
For reference, I've added the method in question here and highlight the one that causes the exception:
public static Bitmap addShadow(Bitmap bitmap) {
try {
BlurMaskFilter blurFilter = new BlurMaskFilter(12, BlurMaskFilter.Blur.OUTER);
Paint shadowPaint = new Paint();
shadowPaint.setMaskFilter(blurFilter);
shadowPaint.setShadowLayer(12, -3, -3, Color.parseColor("#33000000"));
int[] offsetXY = new int[2];
Bitmap shadowImage = bitmap.extractAlpha(shadowPaint, offsetXY);
Bitmap shadowImage32 = shadowImage.copy(Bitmap.Config.ARGB_8888, true);
Canvas c = new Canvas(shadowImage32); // exception occurs here <----
c.drawBitmap(bitmap, -offsetXY[0], -offsetXY[1], null);
return shadowImage32;
} catch (Exception e) {
e.printStackTrace();
}
return bitmap; // if error return the original bitmap
}
I'm facing exactly the same problem in the exactly the same code, but I need to solve this in the Android code, not changing the images outside the app, as I'm using the images loaded from the user's device.
What I've found is the following, just before the canvas call:
// Fix the non pre-multiplied state.
if ( !shadowImage32.isPremultiplied() )
{
shadowImage32.setPremultiplied( true );
}
The problem here is that my min API level is 10, and isPremultiplied() needs API 17 and setPremultiplied( true ) needs API 19.
Edit: I've tested using a device with API 10 and there is no such Exception, so I guess in API 19 they introduced pre-multiply handling and exception. So, finally, my code has these lines:
// Fix the non pre-multiplied exception for API 19+.
if ( android.os.Build.VERSION.SDK_INT >= 19 && !shadowImage32.isPremultiplied() )
{
shadowImage32.setPremultiplied( true );
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With