catch" RuntimeException:Canvas:试图画得太大......"

时间:2017-02-27 21:04:55

标签: android imageview

我有一个应用程序,它将文件系统中的图像绘制到屏幕上,如下所示:

Bitmap image = BitmapFactory.decodeFile(file.getPath());
imageView.setImageBitmap(image);

如果图像非常大,我会看到此错误:

java.lang.RuntimeException: Canvas: trying to draw too large(213828900bytes) bitmap.
    at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:260)
    at android.graphics.Canvas.drawBitmap(Canvas.java:1415)
    ...

堆栈无法访问我的代码。我怎么能抓到这个错误?或者是否有更合适的方法将图像绘制到可以避免此错误的imageView

4 个答案:

答案 0 :(得分:4)

任何应用程序都允许用户选择图片作为背景或在某处绘制,这一定会遇到问题,如果用户拍摄了全景照片或大图片,则您的应用程序必须强行关闭,并且您没有机会防止错误发生,因为您可以捕获异常。

好吧,我只需要捕获Exception并告诉用户我们无法加载图片然后完成,它就太多余了,无法使用Picasso或此类库作为附加功能,android编码受到影响,我不想这样做更多的痛苦。

最后,我在core.java.android.view.DisplayListCanvas中找到了代码,使用变量MAX_BITMAP_SIZE定义了最大图像大小

private static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB

您无法在程序中读取变量,它被定义为私有变量(但是,如果您有任何读取变量的方法,请告诉我),这是引发RuntimeException的部分代码:

int bitmapSize = bitmap.getByteCount();
if (bitmapSize > MAX_BITMAP_SIZE) {
    throw new RuntimeException(
        "Canvas: trying to draw too large(" + bitmapSize + "bytes) bitmap.");
    }

我只是复制上面的部分,检查代码中位图的大小,如果超过100M,则向用户显示消息,上面提到的消息然后结束。

如果您的情况与我相同,希望对您有帮助。

答案 1 :(得分:3)

Bitmap的大小太大,而Bitmap对象无法处理它。因此,ImageView应该有同样的问题。解决方案:在诸如paint.net之类的程序中调整图像大小,或者为位图设置固定大小并缩放它。

在我走得更远之前,你的堆栈跟踪链接到位图的绘图,而不是创建对象:

  

在android.graphics.Canvas.drawBitmap(Canvas.java:1415)

因此你可以这样做:

Bitmap image = BitmapFactory.decodeFile(file.getPath());//loading the large bitmap is fine. 
int w = image.getWidth();//get width
int h = image.getHeight();//get height
int aspRat = w / h;//get aspect ratio
int W = [handle width management here...];//do whatever you want with width. Fixed, screen size, anything
int H = w * aspRat;//set the height based on width and aspect ratio

Bitmap b = Bitmap.createScaledBitmap(image, W, H, false);//scale the bitmap
imageView.setImageBitmap(b);//set the image view
image = null;//save memory on the bitmap called 'image'

或者,作为mentioned here,您也可以使用Picasso

注意

当堆栈跟踪来自时,您尝试加载的映像为213828900 bytes,即213mb。这可能是具有非常高分辨率的图像,因为它们的尺寸越大,它们的字节越大。

对于大图像,带缩放的方法可能无法正常工作,因为它牺牲了太多的质量。由于图像很大,毕加索可能是唯一能够在没有太大分辨率的情况下加载它的东西。

答案 2 :(得分:0)

您应该检查图像的大小并加载较小尺寸的图像以避免异常。请阅读这篇文章:Loading Large Bitmaps Efficiently

您也可以使用Picasso Library

答案 3 :(得分:0)

我修复了LunarWatcher代码中的错误。

Bitmap image = BitmapFactory.decodeFile(file.getPath());
float w = image.getWidth();//get width
float h = image.getHeight();//get height
int W = [handle width management here...];
int H = (int) ( (h*W)/w);
Bitmap b = Bitmap.createScaledBitmap(image, W, H, false);//scale the bitmap
imageView.setImageBitmap(b);//set the image view
image = null;//save memory on the bitmap called 'image'