我正在使用非常大的位图,我将数据存储在一个大的int []中。图像可能非常大,我无法对它们进行下采样(我在线上获取位图并渲染它们)。
我遇到的问题是非常大的位图(位图大小= 64MB),我尝试分配大小为16384000的int数组。我在三星Galaxy SII上测试它,它应该有足够的内存来处理这个,但似乎堆大小有一个“上限”。方法Runtime.getRuntime().maxMemory()
返回64MB,因此这是此特定设备的最大堆大小。
API级别设置为10,因此我无法在其他位置使用android:largeHeap
属性(我甚至不知道这是否会有所帮助)。
有没有办法分配超过64MB?我尝试在本机中分配数组(使用JNI NewIntArray
函数),但也失败了。似乎它受到与jvm相同的限制。
但是我可以使用NewDirectByteBuffer
在本机端分配内存,但由于此字节缓冲区没有数组支持,因此我无法访问int[]
(使用asIntBuffer().array()
为了使用setPixels
或createBitmap
显示图像我需要的java。我想OpenGL是一种方法,但我(迄今为止)有过使用OpenGL的经验。
有没有办法以某种方式将分配的内存作为int []访问我错过了?
答案 0 :(得分:3)
所以,到目前为止我找到的唯一方法是使用NDK分配图像。此外,由于Bitmap不使用现有的Buffer作为像素“存储”(方法copyPixelsFromBuffer
也绑定到内存限制;并且通过方法名称判断,它复制数据)。
解决方案(我只是大致原型)是malloc
无论图像的大小是什么,并使用c / c ++填充它,然后在Java中使用ByteBuffer OpenGLES。< / p>
当前原型创建一个简单的平面并将此图像作为纹理应用于它(幸运的是,OpenGLES方法将Buffer作为输入,这似乎按预期工作)。我正在使用glTexImage2D
将此缓冲区作为纹理应用于平面。这是一个示例,其中mImageData是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);
答案 1 :(得分:0)
我认为OP已经解决了这个问题,但是如果你有一个Stream,你可以将位图流式传输到一个文件中并使用inSampleSize