使用glide加载大尺寸图像时出现OutOfMemoryException [英] OutOfMemoryException while loading large size images using glide

查看:862
本文介绍了使用glide加载大尺寸图像时出现OutOfMemoryException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我一直在使用这个令人惊叹的库 Glide 在我的图库应用中显示本机图像.我正在使用ViewPagerFragmentStatePagerAdapter来显示完整尺寸的图像.传呼机的屏幕外限制为1(默认设置为节省内存).我正在使用此代码将图像加载到片段中的ViewPager中:

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. 加载图像需要花费相当长的时间(如果未缓存).因此,当用户滚动浏览viewpager时,在加载图像时会显示空白屏幕,这是我要避免的事情.有什么办法可以做到吗?也许是通过预缓存图像?
  2. 有时,在滚动查看大尺寸图像(主要是相机照片)时,会抛出 OOM异常,并且由于未加载任何图像,因此用户处于空白屏幕.当我从potrait切换到风景模式时,也会发生这种情况.因此,我尝试使用atMost()之类的方法-由于图像已经加载到RGB_565approximate()中,这进一步降低了图像质量,这也导致了OOM.如何在没有OOM异常的情况下获得最高的图像质量?
  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?

我也尝试使用ARGB_8888,但是结果是一样的:OOM异常.

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

推荐答案

TL; DR

  • 确保ImageView具有match_parent或固定的dp作为尺寸
    wrap_content使Glide加载全分辨率位图.
  • .placeholder()在加载大位图时显示图像而不是空白空间
  • .thumbnail(float)快速加载降采样的版本,而背景中加载较大的图像
  • 也环顾四周滑翔问题,也许您会找到有用的东西.
  • 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.
    • 我想知道ImageView的xml是什么,因为我猜是wrap_content导致将全分辨率的图像加载到Bitmap中(使用大量内存).如果是这种情况,我建议使用match_parent或固定的dp降低分辨率.注意:您不会使用细节,因为当前无论如何在渲染时都会对图像进行降采样,只需将其拉到解码阶段即可.

      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.

      您还必须确保您的应用程序没有内存使用限制.您是否可以加载3(屏幕限制= 1是指将1+current+1)相机照片转换为不带Glide的位图?同样,假设这是全分辨率,则无论有没有Glide,都应该有可能在内存中存储3个屏幕大小的字节,但是您必须指导Glide不要以全分辨率加载.

      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.

      您可以通过.thumbnail()加载较小尺寸的图像,它接受

      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.

      因此,更简单的选择是将.thumbnail()添加到当前负载中.一个更令人费解的问题涉及使用 .sizeMultiplier() 同时创建Fragment的视图,然后在ViewPager更改页面后开始加载高分辨率的视图.这有助于窥视页面.

      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.

      或者,您可以只使用 .placeholder() ,当图像正在加载时,它不是空白空间,而是东西".

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

      关于使用ARGB_8888(每像素32位):如果将内存消耗增加了Bitmap s(与RGB_565(每像素16位)相比),则不要期望以后会耗尽内存.一旦将其与565配合使用,您可以尝试增加,但在那之前尝试是徒劳的.

      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.

      这篇关于使用glide加载大尺寸图像时出现OutOfMemoryException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆