我正在5种设备上测试我的应用程序:三星Galaxy Core,三星S6 edge,Moto G4,小米Redmi note 4和小米MiA1。加载位图在它们上工作正常,但在其他位上则抛出java.lang.RuntimeException: Canvas: trying to draw too large
。您能帮我找到解决办法吗?
日志:
致命异常:java.lang.RuntimeException:画布:尝试绘制 太大(135788800bytes)位图。 在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) 在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) 在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) 在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) 在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) 在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) 在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) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
答案 0 :(得分:1)
尝试执行任何操作之前先压缩所选的图像。
这是压缩等高比图像的代码。
我将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 :(得分:1)
即使通过压缩来减小图像的文件大小,手机上显示的位图仍会占用大量内存。 Bitmap renders every pixel independently,因此是4048x3036 pixels image can take up to 48 Mb of memory
解决方案是在保持所需细节质量的同时降低分辨率。
答案 2 :(得分:0)
您可以使用Picasso调整图片大小:
Picasso.get().load(imageUri).resize(512,512).into(imageView);
在调整大小方法中,这两个数字是图像的目标宽度和高度。随意更改它们(但不要输入太多数字!)。
对我有用。
答案 3 :(得分:0)
如果您的应用使用 Glide:
Glide.with(context).load(uri).into(imageView);