Android画布尝试绘制过大的图形异常

4
我正在对5个设备进行应用程序测试:三星Galaxy Core、三星S6 Edge、Moto G4、小米Redmi Note 4和小米MiA1。在它们上面加载位图正常,但在其他一些设备上会抛出java.lang.RuntimeException: Canvas: trying to draw too large。您能否帮我找到解决方案?
日志:
致命异常:java.lang.RuntimeException: Canvas:尝试绘制太大(135788800字节)的位图。 在android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:229)处抛出 在android.view.RecordingCanvas.drawBitmap(RecordingCanvas.java:97)处绘制位图 在android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:529)处绘制位图 在android.widget.ImageView.onDraw(ImageView.java:1367)处绘制位图 在android.view.View.draw(View.java:20338)处绘制视图 在android.view.View.updateDisplayListIfDirty(View.java:19283)处更新显示列表 在android.view.View.draw(View.java:20061)处绘制视图 在android.view.ViewGroup.drawChild(ViewGroup.java:4421)处绘制子View 在android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)处分发绘制事件 在android.view.View.draw(View.java:20341)处绘制视图 在android.view.View.updateDisplayListIfDirty(View.java:19283)处更新显示列表 在android.view.View.draw(View.java:20061)处绘制视图 在android.view.ViewGroup.drawChild(ViewGroup.java:4421)处绘制子View 在android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)处分发绘制事件 在android.view.View.updateDisplayListIfDirty(View.java:19274)处更新显示列表 在android.view.View.draw(View.java:20061)处绘制视图 在android.view.ViewGroup.drawChild(ViewGroup.java:4421)处绘制子View 在android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)处分发绘制事件 在android.view.View.updateDisplayListIfDirty(View.java:19274)处更新显示列表 在android.view.View.draw(View.java:20061)处绘制视图 在android.view.ViewGroup.drawChild(ViewGroup.java:4421)处绘制子View 在android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)处分发绘制事件 在android.view.View.updateDisplayListIfDirty(View.java:19274)处更新显示列表 在android.view.View.draw(View.java:20061)处绘制视图 在android.view.ViewGroup.drawChild(ViewGroup.java:4421)处绘制子View 在android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)处分发绘制事件 在android.view.View.draw(View.java:20341)处绘制视图 在com.android.internal.policy.DecorView.draw(DecorView.java:979)处绘制视图 在android.view.View.updateDisplayListIfDirty(View.java:19283)处更新显示列表 在android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:686)处更新显示列表 在android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:692)处更新显示列表 在android.view.ThreadedRenderer.draw(ThreadedRenderer.java:800)处绘制视图 在android.view.ViewRootImpl.draw(ViewRootImpl.java:3447)处绘制视图 在android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3234)处执行绘制操作 在android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2769)处遍历视图树 在android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1738)处执行遍历操作 在android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7745)处运行遍历操作 在android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)处运行回调函数 在android.view.Choreographer.doCallbacks(Choreographer.java:723)处执行回调操作 在android.view.Choreographer.doFrame(Choreographer.java:658)处执行绘制操作 在android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)处运行绘制事件接收器 在android.os.Handler.handleCallback(Handler.java:789)处处理回调函数 在android.os.Handler.dispatchMessage(Handler.java:98)处分发消息 在android.os.Looper.loop(Looper.java:164)处循环执行 在android.app.ActivityThread.main(ActivityThread.java:6938)处运行主线程 在java.lang.reflect.Method.invoke(Method.java)处调用方法 在com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)处运行方法和参数

1
可能是Android Studio Canvas:绘制过大的位图的重复问题。 - Abhay Koradiya
1
如果您的drawable文件夹中有任何大型图像,请压缩该图像,然后它将完美运行。 - Darshan Popat
1
图片太大,无法绘制。手机无法分配足够的内存。尝试使用矢量图像或小尺寸图像,而不是高分辨率图像。 - Jevgenij Kononov
135788800字节 / 1000 等于 135788千字节 / 1000 等于 135兆字节,假设每个像素有4个字节(ARGB),则您有135788800 / 4 = 33947200个像素,并且假设为正方形图像:根号33947200 = 5826。您真的要绘制一个5800x5800像素的图像吗? - WarrenFaith
1
实际上,我找到了解决方案,罪魁祸首是启动画面图像,我的设计师做得有些马虎,给了我错误大小的启动画面图像,所以我在模拟器上进行了测试,在像Pixel xl-2这样的大设备和我的同事的手机上应用程序崩溃。图像大小不正确,导致崩溃,他为此给了我新的图像,现在一切正常。 - Obito
4个回答

2

在进行任何操作之前,请尝试压缩您选择的图像。

以下是等比例压缩图像的代码。

我将 Uri 转换为位图。

bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);

我将位图、最大宽度和最小宽度传递给resize()函数。

resizeBitmap = resize(bitmap, bitmap.getWidth() / 2, bitmap.getHeight() / 2);

resize() 方法

private static Bitmap resize(Bitmap image, int maxWidth, int maxHeight) {
    if (maxHeight > 0 && maxWidth > 0) {
        int width = image.getWidth();
        int height = image.getHeight();
        float ratioBitmap = (float) width / (float) height;
        float ratioMax = (float) maxWidth / (float) maxHeight;

        int finalWidth = maxWidth;
        int finalHeight = maxHeight;
        if (ratioMax > ratioBitmap) {
            finalWidth = (int) ((float) maxHeight * ratioBitmap);
        } else {
            finalHeight = (int) ((float) maxWidth / ratioBitmap);
        }
        image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true);
        return image;
    } else {
        return image;
    }
}

1

0
如果您的应用程序正在使用Glide:
Glide.with(context).load(uri).into(imageView);

0

你可以使用Picasso来调整图片大小:

Picasso.get().load(imageUri).resize(512,512).into(imageView);

在resize方法中,这两个数字是您图像的目标宽度和高度。根据您的喜好进行更改(但不要输入太大的数字!)。
对我来说有效。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接