android - 在 Android 上处理大位图 - int[] 大于最大堆大小

标签 android memory android-ndk

我使用非常大的位图,并将数据存储在一个大 int[] 中。图像可能非常大,我无法对它们进行下采样(我通过网络获取位图并渲染它们)。

我遇到的问题是在非常大的位图上(位图大小 = 64MB),我尝试分配大小为 16384000 的 int 数组。我正在 Samsung Galaxy SII 上测试这个,它应该有足够的内存来处理这个问题,但堆大小似乎有一个“上限”。方法Runtime.getRuntime().maxMemory()返回 64MB,因此这是该特定设备的最大堆大小。

API级别设置为10,所以我无法使用android:largeHeap其他地方建议的属性(我什至不知道这是否有帮助)。

有什么办法可以分配超过64MB的空间吗?我尝试在 native 中分配数组(使用 JNI NewIntArray 函数),但也失败了。看起来好像它受到与jvm相同的限制。

但是,我可以使用 NewDirectByteBuffer 在 native 端分配内存,但由于该字节缓冲区不受数组支持,因此我无法访问 int[] (在java中使用asIntBuffer().array(),我需要使用setPixelscreateBitmap来显示图像。我想OpenGL将是一种可行的方法,但我(到目前为止)有0个OpenGL经验。

有没有办法以某种方式访问​​我丢失的 int[] 分配的内存?

最佳答案

所以,到目前为止我发现的唯一方法是使用 NDK 分配图像。此外,由于 Bitmap 不使用现有的 Buffer 作为像素“存储”(方法 copyPixelsFromBuffer 也受到内存限制;并且从方法名称来看,它复制数据无论如何)。

解决方案(我只是大致原型(prototype)化了它)是 malloc 无论图像的大小是什么,并使用 c/c++ 填充它,然后在 Java 中使用 ByteBuffer OpenGLES .

当前的原型(prototype)创建了一个简单的平面,并将该图像作为纹理应用于它(幸运的是,OpenGLES 方法将 Buffer 作为输入,这似乎按预期工作)。我使用 glTexImage2D 将此缓冲区作为纹理应用于平面。这是一个示例,其中 mImageData 是在 native 端分配(并填充)的 ByteBuffer。

int[] textures = new int[1];
gl.glGenTextures(1, textures, 0);
mTextureId = textures[0];
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, 4000, 4096, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, mImageData);

关于android - 在 Android 上处理大位图 - int[] 大于最大堆大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8037821/

相关文章:

c++ - 当我以这种方式修改交换函数时会发生什么?

memory - CUDA 中的固定内存

android - Dagger 不断拒绝注入(inject)依赖

android - 适当的使用短信Android忘记密码的方法

c# - 希望优化 Redis 内存使用以缓存许多 JSON API 结果

Android:无法加载库(94 缺少基本表)

c++ - 为 Android NDK 编译 Boost 库的子集

android - 在android appwidget中实现位置监听器时出现问题

java - 在哪里放置 AdMob 横幅?

android - Eclipse-CDT 无法在 NDK 项目中找到 stdlib 符号