【问题标题】:Memory efficient way to scale an image缩放图像的内存有效方法
【发布时间】:2011-04-14 18:39:01
【问题描述】:

我有一个主要查看区域是 WebView 的应用程序。

这是一项用户还可以上传照片的服务。但是,使用 WebView 和上传照片时,我遇到了一些 OutOfMemoryErrors。

通常只需要在 WebView 中加载一个页面,然后简单地尝试使用以下内容打开一个图像:

Bitmap bmp = BitmapFactory.decodeFile(path);

我需要打开文件的唯一原因是我可以在上传文件之前将其缩小,使其适合最大宽度/最大高度尺寸。

我什至尝试过以采样方式打开它,类似于这里提到的:

Strange out of memory issue while loading an image to a Bitmap object

但是,在 WebView 中加载了复杂的网页,尝试打开图像时仍然出现 OutOfMemoryError。

有没有办法扩展它,也许使用另一个进程或其他东西,这样内存效率更高?

【问题讨论】:

  • 好的,我应该在回答之前点击该链接,因为我刚刚描述了您之前尝试过的方法!您正在使用什么文件格式?如果是像JPEG这样的基于频率的格式,缩放就相当简单了(理论上没试过)
  • 是的,来自设备自带摄像头的 jpeg
  • 查看我编辑的答案(在 cmets 中格式不够!)
  • 缩小后的图片尺寸和分辨率是多少,你是如何打开它的?我注意到您说的是在 WebView 中打开,因此问题可能不是源图像大小。
  • WebView 完全不相关,只是它消耗了大量的内存预算。我没有在那里显示图像或其他任何东西。缩放目前也不是问题。在我尝试缩放之前,简单地使用 BitmapFactory.decode 打开图像当前会导致 OutOfMemoryError。我尝试打开的图像具有可变分辨率,具体取决于拍摄它们的设备。

标签: android


【解决方案1】:

很高兴你问我,我正准备为我自己的项目调查这个问题。

看起来 BitmapFactory.Options 是你的朋友,特别是 BitmapFactory.Options.inSampleSize enter link description here。您可以使用BitmapFactory.decodeStream 获取图像尺寸,而无需创建位图。

谷歌搜索发现了 com.bristle.javalib.awt ImgUtil 类;这些似乎是开源的(不知道许可证),并且基于 AWT,因此可以在 Android 上运行。有趣的方法是ImgUtil.scalueImageToOutputStreamAsJPEG,它与 InputSteam/OutputStream 一起使用,因此可能会节省内存。

更新

另一种方法是围绕 /system/lib/libjpeg.so 编写 JNI 包装器,这似乎是 Android 设备上的标准配置。该库与扫描线一起使用,因此对内存很友好。另一个优点是使用 JNI 应该比纯 java 更快。

希望这会有所帮助,

菲尔·莱洛

【讨论】:

  • 看起来很有希望,虽然 Android 不包含任何来自 AWT 的东西,特别是 Image 和 BufferedImage 不存在。
【解决方案2】:

我遇到了类似的问题,并使用 BitmapFactory.Option.inScale 找到了一个可行的解决方案。您可以在这里找到详细信息:How do I scale a streaming bitmap in-place without reading the whole image first?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-16
    • 2016-08-23
    • 2020-10-29
    • 2015-09-27
    • 1970-01-01
    • 2013-12-29
    • 1970-01-01
    • 2013-05-24
    相关资源
    最近更新 更多