Android 安卓4.4中的新警告
我最近注意到这些异常(已捕获但已登录到logcat):Android 安卓4.4中的新警告,android,image,exception,Android,Image,Exception,我最近注意到这些异常(已捕获但已登录到logcat): W/System.err(2612):java.lang.RuntimeException:画布:尝试使用非预乘位图android.graphics。Bitmap@535924e0 W/System.err(2612):位于android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1088) W/System.err(2612):位于android.graphics.Canvas(Canva
W/System.err(2612):java.lang.RuntimeException:画布:尝试使用非预乘位图android.graphics。Bitmap@535924e0
W/System.err(2612):位于android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1088)
W/System.err(2612):位于android.graphics.Canvas(Canvas.java:139)
System.err(2612):位于com.example.imaging.ImageHelper.addShadow(ImageHelper.java:553)
我试图理解这个异常意味着什么(以及非预乘位图),但我不确定是什么导致了这个异常。我们从服务器获取的图像有问题,还是我们在本地执行的操作有问题?(导致异常的不仅仅是这一行,而是其中之一)
作为参考,我在这里添加了有问题的方法,并突出显示了导致异常的方法:
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
}
公共静态位图addShadow(位图){
试一试{
BlurMaskFilter blurFilter=新的BlurMaskFilter(12,BlurMaskFilter.Blur.OUTER);
绘制阴影绘制=新绘制();
shadowPaint.setMaskFilter(模糊过滤器);
shadowPaint.setShadowLayer(12,-3,-3,Color.parseColor(#33000000));
int[]offsetXY=新的int[2];
位图shadowImage=Bitmap.extractAlpha(shadowPaint,offsetXY);
位图shadowImage32=shadowImage.copy(Bitmap.Config.ARGB_8888,true);
Canvas c=new Canvas(shadowImage32);//这里发生异常我在完全相同的代码中面临完全相同的问题,但我需要在Android代码中解决这个问题,而不是在应用程序外更改图像,因为我使用的是从用户设备加载的图像
在canvas调用之前,我发现了以下内容:
这里的问题是我的最小API级别是10,isPremultiplied()需要API 17,setPremultiplied(true)需要API 19
编辑:我已经使用带有API 10的设备进行了测试,并且没有此类异常,因此我猜在API 19中,他们引入了预乘法处理和异常。因此,最后,我的代码有以下几行:
// Fix the non pre-multiplied exception for API 19+.
if ( android.os.Build.VERSION.SDK_INT >= 19 && !shadowImage32.isPremultiplied() )
{
shadowImage32.setPremultiplied( true );
}
参考Xavi answer,我使用一个非常旧的代码将此方法(用于支持新设备)称为反射:
if ( android.os.Build.VERSION.SDK_INT >= 19 )
{
try {
java.lang.reflect.Method method = shadowImage32.getClass().getMethod("setPremultiplied",boolean.class);
method.invoke(shadowImage32, true);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
我认为这与拥有一个独特的alpha通道有关,而不是将alpha预乘到颜色组件中,以更直接(从而更有效)地生成格式与实际的显示实现兼容。@ChrisStratton这是否意味着我应该在服务器上更改/重新转换图像,还是应该修改addShadow函数?如果您可以接受,在服务器上更改图像可能是运行时最有效的解决方案。
// Fix the non pre-multiplied exception for API 19+.
if ( android.os.Build.VERSION.SDK_INT >= 19 && !shadowImage32.isPremultiplied() )
{
shadowImage32.setPremultiplied( true );
}
if ( android.os.Build.VERSION.SDK_INT >= 19 )
{
try {
java.lang.reflect.Method method = shadowImage32.getClass().getMethod("setPremultiplied",boolean.class);
method.invoke(shadowImage32, true);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}