首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >捕获"RuntimeException: Canvas:尝试绘制过大...“

捕获"RuntimeException: Canvas:尝试绘制过大...“
EN

Stack Overflow用户
提问于 2017-02-28 05:04:55
回答 3查看 20.1K关注 0票数 7

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

代码语言:javascript
复制
Bitmap image = BitmapFactory.decodeFile(file.getPath());
imageView.setImageBitmap(image);

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

代码语言:javascript
复制
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以避免此错误?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-02-28 05:09:14

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

在我继续之前,您的堆栈跟踪链接到位图的绘图,而不是创建对象:

android.graphics.Canvas.drawBitmap(Canvas.java:1415)上的

因此,您可以执行以下操作:

代码语言:javascript
复制
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。这可能是一个非常高分辨率的图像,因为它们的大小越大,它们的字节数就越大。

对于如此大的图像,缩放方法可能不起作用,因为它牺牲了太多的质量。对于如此大的图像,毕加索或Glide可能是在不损失太大分辨率的情况下加载图片的唯一选择。

票数 4
EN

Stack Overflow用户

发布于 2018-11-16 17:06:40

任何应用程序允许用户选择图片作为背景或在某个地方绘制,它必须计算问题,如果用户选择了全景照片或大图片,您的应用程序必须强制关闭,而您没有机会防止MISTACK,因为您无法捕获异常。

好的,我只需要捕获异常并告诉用户我们不能加载图片然后完成,使用毕加索或这样的库来实现额外的功能太多余了,android编码是痛苦的,我不想让它更痛苦。

最后,我在core.java.android.view.DisplayListCanvas中找到了代码,其中定义了一个带有变量MAX_BITMAP_SIZE的最大图像大小

代码语言:javascript
复制
private static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB

你不能在你的程序中读取这个变量,它被定义为私有的(但是如果你有办法读取这个变量,请告诉我),下面是抛出RuntimeException的部分代码:

代码语言:javascript
复制
int bitmapSize = bitmap.getByteCount();
if (bitmapSize > MAX_BITMAP_SIZE) {
    throw new RuntimeException(
        "Canvas: trying to draw too large(" + bitmapSize + "bytes) bitmap.");
    }

我只是复制上面的部分,检查我的代码中的位图大小,如果它超过100M,那么显示消息给用户,我上面提到的消息,然后完成。

如果你的情况和我一样,希望能对你有所帮助。

票数 8
EN

Stack Overflow用户

发布于 2017-06-19 09:15:52

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

代码语言:javascript
复制
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'
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42495741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档