I have an application which draws an image from the file system to screen like so:
Bitmap image = BitmapFactory.decodeFile(file.getPath());
imageView.setImageBitmap(image);
If the image is very large I see this error:
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)
...
The stack does not reach my code. How can I catch this error? Or is there a more appropriate way to be drawing the image to the imageView
that can avoid this error?
The Bitmap is too large in size and the Bitmap object cannot handle it. Thus, ImageView should have the same problem. Solution: resize the image either in programs such as paint.net, or set a fixed size for the bitmap and scale it.
Before I go further, your stacktrace links to the drawing of the bitmap, not creating the object:
at android.graphics.Canvas.drawBitmap(Canvas.java:1415)
As such you can do this:
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'
Or, as mentioned here, you can use Picasso as well
NOTE
The image you attempted to load in when the stacktrace is from, is 213828900 bytes
, which is 213mb. This is probably an image with very high resolution, as the bigger in size they are, the bigger in bytes they are.
With images that big, the method with scaling may not work as it sacrifices too much of the quality. With images that big, Picasso or Glide may be the only options that loads in the pictures without a too big loss of resolution.
Any app allow user pick picture as background or draw somewhere, it must encount the problem, if user pickup a panoramic photograph or big picture your app must force close, and YOU HAVE NO CHANCE TO PREVENT THE MISTACK, because you can't catch the Exception.
Ok, I just need catch the Exception and tell user we can't load the picture then finish, it too redundant to use Picasso or such library for the additional function, android coding is suffer and I don't want make it more suffer.
finally, I found the code in core.java.android.view.DisplayListCanvas, there is define a max image size with variable MAX_BITMAP_SIZE
private static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB
You couldn't read the variable in your program, it's define as private(but if you have any way to read the variable please let me know), and here is the part code that throw RuntimeException:
int bitmapSize = bitmap.getByteCount();
if (bitmapSize > MAX_BITMAP_SIZE) {
throw new RuntimeException(
"Canvas: trying to draw too large(" + bitmapSize + "bytes) bitmap.");
}
I just copy the part above, check the size of bitmap in my code, if it over 100M then show message to user the message I mention above then finish.
If your case is the same with me, hope it help you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With