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

时间:2011-01-27 10:29:43

标签: android image-processing out-of-memory

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

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

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

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

3 个答案:

答案 0 :(得分: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);

简单:)

答案 1 :(得分:1)

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

如果输入图形是PNG格式,那么同样的技术也可以使用,或者只要你能找到合适的解码代码就可以使用其他任何技术。

我认为通过分段加载图像,你在设定自己的算法挑战时,决定你对它的全部细节真正感兴趣的部分。我注意到BitmapFactory.Options包含子样本选项,如果您想分析图像的概述以确定要加载的详细区域,这可能很有用。

答案 2 :(得分:1)

如果您正在处理JPEG图片,请参阅我对this question以及this example的回答。

我不知道在Android上获取libijg是多么可能,但如果是,那么它值得一试。