Reputation: 69
I am testing my app on 5 devices: Samsung Galaxy core, Samsung S6 edge, Moto G4, Xiaomi Redmi note 4 and Xiaomi MiA1. Loading bitmaps works fine on them but on some other it throws java.lang.RuntimeException: Canvas: trying to draw too large
. Can you help me find a solution?
Log:
Fatal Exception: java.lang.RuntimeException: Canvas: trying to draw too large(135788800bytes) bitmap. at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:229) at android.view.RecordingCanvas.drawBitmap(RecordingCanvas.java:97) at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:529) at android.widget.ImageView.onDraw(ImageView.java:1367) at android.view.View.draw(View.java:20338) at android.view.View.updateDisplayListIfDirty(View.java:19283) at android.view.View.draw(View.java:20061) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.draw(View.java:20341) at android.view.View.updateDisplayListIfDirty(View.java:19283) at android.view.View.draw(View.java:20061) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.updateDisplayListIfDirty(View.java:19274) at android.view.View.draw(View.java:20061) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.updateDisplayListIfDirty(View.java:19274) at android.view.View.draw(View.java:20061) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.updateDisplayListIfDirty(View.java:19274) at android.view.View.draw(View.java:20061) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.updateDisplayListIfDirty(View.java:19274) at android.view.View.draw(View.java:20061) at android.view.ViewGroup.drawChild(ViewGroup.java:4421) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207) at android.view.View.draw(View.java:20341) at com.android.internal.policy.DecorView.draw(DecorView.java:979) at android.view.View.updateDisplayListIfDirty(View.java:19283) at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:686) at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:692) at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:800) at android.view.ViewRootImpl.draw(ViewRootImpl.java:3447) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3234) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2769) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1738) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7745) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911) at android.view.Choreographer.doCallbacks(Choreographer.java:723) at android.view.Choreographer.doFrame(Choreographer.java:658) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897) at android.os.Handler.handleCallback(Handler.java:789) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6938) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Upvotes: 5
Views: 19475
Reputation: 4811
If your app is using Glide:
Glide.with(context).load(uri).into(imageView);
Upvotes: 0
Reputation: 1371
You can use Picasso to resize your image:
Picasso.get().load(imageUri).resize(512,512).into(imageView);
In resize method, the 2 numbers are the target width and height of your image. Change them as you like (but don't put too large numbers!).
It worked for me.
Upvotes: 0
Reputation: 708
Even if you reduce the file size of your image by compressing it, the Bitmap shown on the phone will still take substantial amount of memory. Bitmap renders every pixel independently and therefore a 4048x3036 pixels image can take up to 48 Mb of memory
The solution would be to reduce the resolution while maintaining desirable detail quality.
Loading Large Bitmaps Efficiently
Upvotes: 1
Reputation: 195
Try to compress your selected image before doing any action.
Here is the code that compress image with equal aspect ratio.
I converted Uri to bitmap
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
The i pass the bitmap, maxwidth, minWidth to resize().
resizeBitmap = resize(bitmap, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
resize() method
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;
}
}
Upvotes: 2