是否可以将位图切成小块而不将整个内容加载到内存中?

Off*_*fCS 19 android image-processing out-of-memory

我正在开发一款适用于Android的图像处理应用程序,可识别音乐表中的音乐符号.

我尝试使用BitmapFactory.decodeFile(imgPath)方法将整个图像加载到Bitmap中,但由于我的手机没有足够的内存,因此出现"VM堆大小"错误.为了解决这个问题,我想将整个图像切成小块,但我不知道该怎么做.

我还看到可以通过使用BitmapFactory.Option类的inSampleSize属性来减少Bitmap的内存大小,但如果我这样做,我将无法获得音乐符号识别过程所需的高分辨率图像.

无论如何都可以在不去NDK的情况下处理这个问题?

Rom*_*Guy 29

Android 2.3.3有一个名为android.graphics.BitmapRegionDecoder的新API,可让您完全按照自己的意愿行事.

例如,您可以执行以下操作:

BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(myStream, false);
Bitmap region = decoder.decodeRegion(new Rect(10, 10, 50, 50), null);
Run Code Online (Sandbox Code Playgroud)

简单 :)

  • 您可以从git存储库中获取代码并在您的应用中使用它:) (3认同)
  • 我编写了一个如何使用`BitmapRegionDecoder` API的例子(https://github.com/johnnylambada/WorldMap).该示例具有一个大的(6000,4000)世界图像,用户可以以全分辨率滚动. (3认同)

cra*_*cot 1

如果来自相机,则图像可能是 jpeg 格式。您可以使用外部 jpeg 库 - 无论是在 java 中还是通过 NDK,无论您能找到什么 - 都可以让您更好地控制并一次加载它。如果您需要它,android.graphics.Bitmap那么我怀疑您需要将子图像重新编码为 PNG 或 JPEG 并将其传递给BitmapFactory.decodeByteArray(). (如果内存是一个问题,那么请务必立即忘记对位图片段的引用,以便垃圾收集器可以有效运行。)

如果输入图形是 PNG 格式或任何其他格式,只要您能找到合适的解码代码,同样的技术也适用。

我认为,通过分段加载图像,您正在为自己设置一个算法挑战,以决定您真正对图像的哪些部分的全部细节感兴趣。我注意到其中BitmapFactory.Options包括子采样选项,如果您想分析图像的概述以决定要加载哪些区域的详细信息,这可能会很有用。