从URL加载高像素图片在滚动视图中,如何避免将整个图片加载到内存中

8
我正在寻找一个库或一些想法,如何从磁盘或url逐部加载图像并再次将其分段到RAM中。所以我看到这可以通过直接从URL读取和写入到磁盘上将整个图像加载到RAM中的缓冲区来完成,然后当图像在磁盘上时,以某种方式创建仅部分图像的位图,这样我就不需要全部加载它,并将其放入ListView中。
问题是,我正在处理非常长的图像(长度超过10K像素,宽度为4-600),如果一次性加载所有内容到一个位图中,它们会占用大量的RAM。我不能像Google Android教程中的大型位图处理部分那样简单地缩小它们,因为这会导致宽度太小而无法处理。因此,如果我能在磁盘上生成小的位图片段,则可以通过在ListView中加载它们来避免将整个图像加载到RAM中。
现在我正在从位图中将长图像分割成片段,但我意识到这并没有真正实现我想要做的事情,因为整个图像都加载到内存中的一个位图中,然后将其拆分,最后进行GC(所以我仍然使用了全部RAM)。我正在新的顶级Android手机上测试应用程序,它的表现良好,但随着较大图像在内存中临时拆分,堆大小达到80mb+,这在具有较低堆限制的设备上将成为问题。
4个回答

2

这难道不需要我将图像加载到位图中并存入内存吗?这正是我想要避免的。谢谢。 - Osman

1
如果您使用Java,则可以使用InputStreamReader和OutputStreamWriter。方法read()接受缓冲区作为其中一个参数,其长度可以是任何适当的值。当然,您可以为每个要写入的缓冲区创建一个新文件。
这是您要找的内容吗?
编辑 嗯,不是。您看到了这个Strange out of memory issue while loading an image to a Bitmap object

我如何知道每个部分中有多少图像,我需要有与图像宽度相同的薄片和任意高度,以便我可以将它们设置在列表视图中。 - Osman
抱歉,我最近有些忙,但是我没有找到与你的代码相匹配的安卓版本。比如说 PNG。 - Osman
我刚刚查看了你指向的问题,但它并没有帮助,因为使用缩小方法会减小高度和宽度,而在长图像上这样做会导致宽度非常小。当我说长图像时,我指的是10k+像素。 - Osman

0
  1. 如果您能控制从哪里获取数据的服务器,请在响应中添加另一个字段,使其返回缩略图/较小的图像。服务器可以为您生成所需的缩略图,而您无需费心。

  2. 动态解码位图可能会很昂贵,大多数情况下都是如此。如果您无法更改服务器上的任何内容,请下载并保存图像,保存后生成相应的缩略图并保存。在列表中使用缩略图。同时,保存有关已缓存的图像以及您已经拥有的缩略图的信息。这看起来可能需要花费很多工作量,但根据用例,这可能是处理大型图像的更好方法。

缩小尺寸存在问题? 好吧,您可以设计一些逻辑来生成缩略图,基于图像的原始大小。对于比较长的(纵向长的)图像,您可以像@Binh Tran建议的那样使用BitmpapRegionDecoder (http://developer.android.com/reference/android/graphics/BitmapRegionDecoder.html)。


0

尝试对图像进行编码,使其大小变小。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接