首页 文章

Android Canvas试图绘制太大的异常

提问于
浏览
1

我在5台设备上测试我的应用程序:三星Galaxy核心,三星S6边缘,Moto G4,小米Redmi note 4和小米MiA1 . 加载位图在它们上工作正常,但在其他一些上它会抛出 java.lang.RuntimeException: Canvas: trying to draw too large . 你能帮我找一个解决方案吗?

日志:

致命异常:java.lang.RuntimeException:Canvas:尝试绘制太大(135788800bytes)的位图 . 在Android.view.RecordingCanvas.drawBitmap(RecordingCanvas.java:97)的android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:229)上的android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:529) . 在Android.view.View.draw.draw的Android.view.View.David(View.java:19283)的android.view.View.draw(View.java:20338)上的widget.ImageView.onDraw(ImageView.java:1367) (View.java:20061)位于android.view.View.Go.(View.java:在android.view.View.::::::: 20341)在android.view.View.View.David(View.java:2002)上的android.view.View.View.View.Still((View.java:2002))安卓android.view.View . 在Android.view.View.View.draw(现场 . ) (ViewGroup.java:4421)在android.view.ViewGroup.d ispatchDraw(ViewGroup.java:4207)位于android.view.View.View.draw((View.java:19274),位于android.view.View.draw上的android.view.View.draw(View.java:20061) . (ViewGroup.java:2207)ViewGroup.java :4421)在android.view.View.DisplayListIfDirty(View.java:19274)的android.view.View.View.David(View.java:19274)android.view.view.D .view.ViewGroup.drawChild(ViewGroup.java:4421)位于android.view.View.View.View.View.View上的android.view.View.上的android.view.View.View.Av上的View.java:19274的android.view.ViewGroup . 在Android.view.View.draw.draw(View.java)的android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)的android.view.ViewGroup.drawChild(ViewGroup.java:4421)中绘制(View.java:20061) :20341)在android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java)的android.view.View.updateDisplayListIfDirty(View.java:19283)的com.android.internal.policy.DecorView.draw(DecorView.java:979) 686)在android.view.ThreadedRenderer.updateR位于android.view.ViewRootImpl.draw(ViewRootImpl.java:3447)的android.view.ThreI上的android.view.ThredeRerImpl.draw(ViewRootImpl.java:3447)中的android.view.ThreadedRenderer.draw(ThreadedRenderer.java:800)的ootDisplayList(ThreadedRenderer.java:692)(ViewRootImpl.java) :3234)在android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1738)上的android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2769)在android.view.ViewRootImpl $ TraversalRunnable.run(ViewRootImpl.java:7745)在android.view.Chore的上面的android.view.Choreographer.doFrame(Choreographer.java:658)的android.view.Choreographer $ CallbackRecord.run(Choreographer.java:911)上的android.view.doCallbacks(Choreographer.java:723) . 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)位于com.andro的java.lang.reflect.Method.invoke(Method.java)的android.app.ActivityThread.main(ActivityThread.java:6938) id.internal.os.Zygote $ MethodAndArgsCaller.run(Zygote.java:327)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

2 回答

  • 1

    即使您通过压缩来缩小图像的文件大小,手机上显示的位图仍会占用大量内存 . Bitmap renders every pixel independently因此4048x3036 pixels image can take up to 48 Mb of memory

    解决方案是降低分辨率,同时保持理想的细节质量 .

    Loading Large Bitmaps Efficiently

  • 1

    在执行任何操作之前,请尝试压缩所选图像 .

    这是压缩具有相同宽高比的图像的代码 .

    我将Uri转换为位图

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

    我将位图,maxwidth,minWidth传递给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;
        }
    }
    

相关问题