在Android上处理大型位图 - INT []比最大堆大小 [英] Handling large bitmaps on Android - int[] larger than max heap size

查看:187
本文介绍了在Android上处理大型位图 - INT []比最大堆大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是非常大的位图,我存储在一个大的INT []的数据。这些图像可真大,我不能下采样他们(我得到的位图通过线路和渲染它们)。

I'm using very large bitmaps and I store data in a big int[]. The images can be really large and I can't downsample them (I'm getting the bitmaps over the wire and rendering them).

我打的问题是非常大的位图(位图大小= 64MB),在那里我尝试分配int数组大小为16384000.我对三星Galaxy SII,测试这里面应该有足够的内存来处理这个,但似乎没有对堆大小上限。该方法调用Runtime.getRuntime()。maxMemory()返回64MB,所以这是最大堆大小为这个特定的设备。

The problem I'm hitting is on very large bitmaps (bitmap size = 64MB), where I try to allocate int array with size 16384000. I'm testing this on Samsung Galaxy SII, which should have enough memory to handle this, but it seems there is a "cap" on heap size. The method Runtime.getRuntime().maxMemory() returns 64MB, so this is the max heap size for this particular device.

该API级别设置为10,所以我不能使用安卓largeHeap 属性别处建议(我甚至不知道这是否会帮助)。

The API level is set to 10, so I can't use android:largeHeap attribute suggested elsewhere (and I don't even know if that would help).

有没有什么办法来分配超过64MB?我试图分配在本地阵列(使用JNI NewIntArray 功能),但失败也是如此。它看起来好像是受相同的极限JVM。

Is there any way to allocate more than 64MB? I tried allocating the array in native (using JNI NewIntArray function), but that fails as well. It seems as though it is bound by the same limit as jvm.

我却可能在本机端使用 NewDirectByteBuffer 分配内存,但由于此字节缓冲区不是由数组支持,我无法访问 INT [] (使用 asIntBuffer()。数组()在Java中,我需要为了使用显示图像的setPixels createBitmap 。我想OpenGL的将是一段路要走,但我有(到目前为止)0经验的OpenGL。

I could however allocate memory on the native side using NewDirectByteBuffer, but since this byte buffer is not backed by an array, I can not get access to int[] (using asIntBuffer().array() in java which I need in order to display the image using setPixels or createBitmap. I guess OpenGL would be a way to go, but I have (so far) 0 experience with OpenGL.

有没有以某种方式地访问分配内存的方式INT [],我很想念?

Is there a way to somehow access allocated memory as int[] that I am missing?

推荐答案

所以,我到目前为止发现的唯一方法是使用NDK分配图像。此外,由于位图不使用现有的缓冲区像素存储(法 copyPixelsFromBuffer 也势必内存限制,并通过方法的名称来看,它的拷贝的数据是这样)。

So, the only way I've found so far is to allocate image using NDK. Furthermore, since Bitmap does not use existing Buffer as pixel "storage" (the method copyPixelsFromBuffer is also bound to memory limits; and judging by the method name, it copies the data anyway).

解决方案(我只是原型它大致)是的malloc 无论图像的大小,并使用C / C填充++,然后使用ByteBuffer的中Java中使用 OpenGLES

The solution (I've only prototyped it roughly) is to malloc whatever the size of the image is, and fill it using c/c++ and then use ByteBuffer in Java with OpenGLES.

目前的原型创建一个简单的平面,并应用这种图像作为纹理它(幸运的是,OpenGLES方法取缓冲输入,这似乎工作如预期)。我使用 glTexImage2D 来申请这个缓冲区作为纹理到一个平面上。下面是一个示例,其中mImageData是ByteBuffer的分配(和填充)对本机端。

The current prototype creates a simple plane and applies this image as a texture to it (luckily, OpenGLES methods take Buffer as input, which seems to work as expected). I'm using glTexImage2D to apply this buffer as a texture to a plane. Here is a sample, where mImageData is ByteBuffer allocated (and filled) on the native side.

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上处理大型位图 - INT []比最大堆大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆