2014-01-17 4 views
1

Я использую библиотеку GPUImage для создания скриншотов/эффектов. Однако на моем Acer Liquid Express с Gingerbread 2.3 он работает только для макс. 1280x720. Попытка установить значение 1600x1200 вызывает размер растрового изображения превышает бюджет VM и VM не позволит нам выделить 7680000 байт. Погружение в код, который я нашел следующее:Уменьшить память в андроиде OpenGL-камера

IntBuffer ib = IntBuffer.allocate(mWidth * mHeight); 
IntBuffer ibt = IntBuffer.allocate(mWidth * mHeight); 

mGL.glReadPixels(0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, ib); 

// Convert upside down mirror-reversed image to right-side up normal 
// image. 
for (int i = 0; i < mHeight; i++) { 
for (int j = 0; j < mWidth; j++) { 
ibt.put((mHeight - i - 1) * mWidth + j, ib.get(i * mWidth + j)); 
} 
} 
mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888); 
mBitmap.copyPixelsFromBuffer(ibt); 

Как вы можете видеть, это создает 2 буфера, 7680000 байт каждый (1600x1200 * 4) и повернуть его вспять из-за различных 0,0 координат в OpenGL и Java. Я хочу, чтобы удалил второй буфер (чтобы сохранить память) и сохранить функциональность. Является ли это возможным? Если я просто удалю ibt и за, он создает обратное изображение без исключения OutOfMemory. Кроме того, будет полезно сохранить растровое изображение RGB_565, но я абсолютно не знаком с OpenGL. Пожалуйста посоветуй.

+0

Вам действительно нужен альфа-канал? Много раз в пиксельном формате фреймбуфера по умолчанию даже нет битовой плоскости альфа-адресата. И даже когда это происходит, он много раз не нуждается в этом. Вы можете сократить размер на 1/4, если вы его устраните. –

+0

@ AndonM.Coleman Мне не нужен альфа-канал. Не могли бы вы правильно изменить исходный код? – Eugene

ответ

0

Да, это вполне возможно. Если вы хотите сделать это на CPU, вам потребуется только временное хранилище, чтобы удерживать одну строку пикселей. Для того, чтобы перевернуть вертикально вы подкачки линии вверх дном наиболее наиболее по направлению к вертикальному центру, используя обычный

temp = a 
a = b 
b = temp 

подход, где а и Ь строки из большого буфера. Для горизонтального флипа вы делаете то же самое внутри линии.

Или вы не шутите с буферами вообще и использовать OpenGL переворачивать изображения, прежде чем руки (рендеринг в FBO с началом в другом углу)

+0

Было бы здорово, если бы вы показали, как это сделать на основе моего исходного кода. – Eugene

0

Вот частичного решения кода к вашей проблеме. Я обычно не переписываю код, когда его спрашивают, особенно на языке, который я никогда не использую, как Java, но мне было скучно.

ShortBuffer sb = ShortBuffer.allocate (mWidth * mHeight); // 2 Bytes per-pixel 
ShortBuffer sbt = ShortBuffer.allocate (mWidth * mHeight); // 2 Bytes per-pixel 

mGL.glReadPixels (0, 0, mWidth, mHeight, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, sb); 

// Convert upside down mirror-reversed image to right-side up normal 
// image. 
for (int i = 0; i < mHeight; i++) { 
    for (int j = 0; j < mWidth; j++) { 
    sbt.put ((mHeight - i - 1) * mWidth + j, sb.get (i * mWidth + j)); 
    } 
} 

sbt.flip(); // Rewind the buffer 

mBitmap = Bitmap.createBitmap (mWidth, mHeight, Bitmap.Config.RGB_565); 
mBitmap.copyPixelsFromBuffer (sbt); 

Это позволит сократить размер обоих ваших буферов в два раза, но это не решает проблему листать изображения на месте. Если вы это сделаете, вы можете сократить необходимое хранилище еще на 50%. Я оставлю это вам, ответ datenwolf должен предоставить вам необходимую информацию, чтобы сделать это самостоятельно.

+0

Благодарим вас за помощь, однако ваш код генерирует ** Буфер, недостаточно большой для пикселей ** Исключение в последней строке 'mBitmap.copyPixelsFromBuffer (sbt);' – Eugene

Смежные вопросы