Brian Rak
Brian Rak

Reputation: 5154

"Canvas: trying to draw too large bitmap" when Android N Display Size set larger than Small

I have a published app that is crashing at startup on Android N when the newly introduced Display size OS setting is set to too large a value.

When I look in logcat, I see the following message:

java.lang.RuntimeException: Canvas: trying to draw too large(106,975,232 bytes) bitmap.

I've traced the issue to an ImageView in my first Activity that shows a nice big background image. The image in question is 2048x1066 and is in my generic drawables directory, so no matter the density, this image will be used.

Everything works okay when the Display size setting is Small. But when I go up to Default, it stops working. If I then swap the image out with a smaller one, it works at Default, but if I go up to Large, it stops working again.

My guess is that adjusting Display size up causes your device to behave like a physically smaller device with a higher pixel density. But I don't understand what I'm supposed to do here. If I put in progressively smaller images for progressively higher resolutions, it won't look good on actually large displays. Or am I not understanding something?

Any pointers would be greatly appreciated.

Upvotes: 103

Views: 131141

Answers (15)

Arbaz Alam
Arbaz Alam

Reputation: 1382

The problem:

So lets say you have a 2000x2000 image, so the image when loaded in Ram should be: 2000 * 2000 * 4 (considering that image is RGBA so multiplying by 4) = 16,000,000 bytes. Divide the total bytes by 1000*1000 to convert it into megabytes we get 16 MB. So the image will take 16 mb of ram which isn't the problem and the image should load even if the storage taken by image is 5mb or more. The problem is that the default drawable folder is a density folder which has some default medium density, so when loading any image from this folder android scales up the size leading to "drawing too large exception" .

The solution:

Right click res folder -> select "Android Resource Directory" -> Select resource type as drawable -> select "Density" from available qualifiers -> click ">>" then select "No density" from list of density -> click ok. Now move the large images in this folder, no changing in code required.

Similarly, you can use the BitmapFactory options and set inScaled attribute to false when loading bitmap to get a non-scaled bitmap.

Upvotes: 0

Erick Kaira
Erick Kaira

Reputation: 11

i solved the problem by simply changing the image extension to .png extension, and it worked just fine with me.

Upvotes: 0

Muhammad Faisal
Muhammad Faisal

Reputation: 906

Just an addition to the Johan Franzén's answer, maybe it's a good idea to not only add drawable-xxhdpi density folder, but also add another density folder.
So whatever the android version and size, your app can prepare the image source with the right size :

  1. Change your folder view on the top left from Android to Project
  2. Go to YourProjectFolder folder > app > src > main > res
  3. Prepare the original image with your best resolution, and split it into each folder size automatically. You can do it in Baker
  4. Then create a folder with another density, namely:
  5. drawable-hdpi, drawable-ldpi, drawable-mdpi, drawable-xhdpi, drawable-xxhdpi, drawable-xxxhdpi
  6. Put each image into the appropriate folder

Upvotes: 0

Mahendren Mahisha
Mahendren Mahisha

Reputation: 1062

Need to add Manifest file's application tag in between android: add below lines.

android:hardwareAccelerated="false"

Upvotes: 0

Balu mallisetty
Balu mallisetty

Reputation: 733

There are some scenarios where Original Bitmap needs be Drawn into ImageViews, Photo Editing apps etc...,

as bay mentioned above setting

android:hardwareAccelerated="false"

will Cause bad UI experince, You can set hardwareAccelerated Only one selected Activity where high res image to be drawn

<application android:hardwareAccelerated="true">
    <activity ... />
    <activity android:hardwareAccelerated="false" />
</application>

Upvotes: 6

HosseinRezaie
HosseinRezaie

Reputation: 31

it is solved by resizing the images to a lower size.

Upvotes: 0

CHAMCHOUN
CHAMCHOUN

Reputation: 779

I solved the problem after adding the below code into the Manifest file's application tag in between android: lines.

android:hardwareAccelerated="false"

Upvotes: 57

Deniz
Deniz

Reputation: 325

if you use Picasso change to Glide like this.

Remove picasso

Picasso.get().load(Uri.parse("url")).into(imageView)

Change Glide

Glide.with(context).load("url").into(imageView)

More efficient

Upvotes: 1

Vishaljoshi007
Vishaljoshi007

Reputation: 1

In my case, I just changed the canvas of image which is used in the background using Paint3d(or you can use any other). Here I am sharing a screenshot just go through it.

Upvotes: 0

Deepak Rajput
Deepak Rajput

Reputation: 761

if you are using glide and you are loading 1k of images at a time or some images then it is issue of glide or whatever you are doing to use to set the image view. you can resolve it just by applying scale type in glide.

Upvotes: 0

kazimad
kazimad

Reputation: 954

I don't know would it help some one, but I'll just leave it here. In my case - problem was only on Sumsung devices with Android 7, and problem was in splash screen proportions. after changing height to 1024 px - everything works fine

Upvotes: 15

lloydyu24
lloydyu24

Reputation: 849

The icon files are too large for Android to efficiently and smoothly load. Android recognizes this with its smart algorithms.

You can resize the icon files using Final Android Resizer by asystat. Resize them to "xhdpi" or lower.

Place the resized photos in drawable or overwrite over the existing large icon files.

Then, you're done.

Upvotes: 0

kalsara Magamage
kalsara Magamage

Reputation: 263

Move your image in the drawable to mipmap-xxhdpi.Your image is in bitmap format so you should put your image in mipmap folder,then it will work

Upvotes: 9

Khalid Ali
Khalid Ali

Reputation: 373

Try to use Bitmap.Factory class, this link will help you Loading Large Bitmaps Efficiently

Upvotes: 3

Johan Franz&#233;n
Johan Franz&#233;n

Reputation: 2424

I my case, moving the (hi-res) splash bitmap from drawable to drawable-xxhdpi was the solution.

I had the same problem. I didn't suspect my splash screen to be the problem, since it is displayed when the app is started, but it turned out the splash screen is the problem.

The splash screen in my case has xxhdpi resolution, and it was mistakenly placed in the drawable folder, instead of drawable-xxhdpi. This made Android assume the splash screen had mdpi resolution and scale the image to 3*3 times it's required size and trying to create a bitmap.

Upvotes: 192

Related Questions