Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OutOfMemoryException while loading large size images using glide

So, I have been using this amazing library Glide for showing native images in my gallery app. I am using ViewPager with FragmentStatePagerAdapter to show full size images. The pager's off screen limit is 1 (default to save memory). I am using this code to load images into ViewPager in my fragment:

Glide.with(getActivity())
     .loadFromMediaStore(uri)
     .asBitmap()
     .signature(new MediaStoreSignature(mimeType, dateModified, 
     .into(mImageView);

Now, I am facing some issues here like:

  1. Images take quite some amount of time to load (if not cached). So, while user is scrolling through the viewpager blank screen is shown while image is loading which is what I want to avoid. Is there any way I can do this? Maybe by precaching images?
  2. Sometimes, while scrolling through large size images (mainly Camera photos) OOM Exception is thrown and user is left with blank screen as no image is loaded. This also happens when I am shifting from potrait to landscape mode. So, I tried to use methods like atMost() -- which degrade the quality of image further as images are already loaded in RGB_565 and approximate() which is also causing OOM. How can I achieve maximum image quality without getting OOM exceptions?

For the second issue, I was thinking to load lesser quality images for the off screen items and then enhance quality when they come on-screen. Is it possible?

I have also tried to use ARGB_8888 but the result was same: OOM exception.

like image 789
harry perry Avatar asked Jun 08 '15 20:06

harry perry


1 Answers

TL;DR

  • Make sure the ImageView has match_parent or fixed dp as dimensions
    wrap_content makes Glide load full resolution Bitmaps.
  • .placeholder() shows an image instead of empty space while loading large bitmap
  • .thumbnail(float) loads a downsampled version fast while the bigger image is loading in the background
  • Also look around the Glide issues, maybe you find something helpful.

Details

I would be curious what the xml is for the ImageView, because my guess is it's wrap_content which results in loading images at full resolution into Bitmaps (using a lot of memory). If that's the case I would suggest using match_parent or fixed dp to lower the resolution. Note: you won't use detail, because currently the image is downsampled at render time anyway, just pulling that forward to decoding phase.

You also have to make sure that your app doesn't have constraints for memory usage. Can you load 3 (off screen limit = 1 means 1+current+1 pages) camera photos into Bitmaps without Glide? Again, assuming this is full resolution, it should be possible to store 3 screen size amount of bytes in memory with or without Glide, but you have to guide Glide to not load at full resolution.

You can load smaller sized image via .thumbnail(), it accepts a full Glide.with... not including .into() OR there's a shorthand parameter which is just a percentage (in 0.0 ... 1.0), try the latter first. It should decode the image much faster, especially with a really small number like 0.1 and then when higher quality one finishes it's replaced.

So the simpler option is to add .thumbnail() to your current load. A more convoluted one involves to start loading a lower resolution image with .sizeMultiplier() at the same time the Fragment's view is created and then start loading the high resolution one when the ViewPager has changed page. This helps with peeking the pages.

Alternatively you can just use a .placeholder() while the image is loading so it's not empty space, but "something" there.

Regarding using ARGB_8888 (32 bit per pixel): if you increase the memory consumed by Bitmaps (compared to RGB_565 (16 bit per pixel) don't expect to get run out of memory later. Once you get it working with 565 you can try increasing, but until then it's futile trying.

Also look around the Glide issues, maybe you find something helpful.

like image 128
TWiStErRob Avatar answered Sep 21 '22 03:09

TWiStErRob