Как получить информацию о 24-битном цвете с помощью glReadPixels() на Android?
Чтобы сохранить обработанное изображение с помощью OpenGL ES, я сделал следующие коды. И это хорошо работает.
ByteBuffer bb = ByteBuffer.allocate(mWidth * mHeight * 4);
mGL.glReadPixels(0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, bb);
try {
TJCompressor tjCompressor = new TJCompressor(bb.array(), 0, 0, mWidth, 0, mHeight, TJ.PF_RGB);
tjCompressor.setJPEGQuality(100);
tjCompressor.setSubsamp(TJ.SAMP_444);
return tjCompressor.compress(0);
} catch (Exception e) {
e.printStackTrace();
}
После этого, чтобы получить 24-битную информацию о цвете без альфа-канала для экономии памяти и времени обработки, я изменил строки № 1 и № 2 кодов следующим образом.
ByteBuffer bb = ByteBuffer.allocate(mWidth * mHeight * 3);
mGL.glReadPixels(0, 0, mWidth, mHeight, GL_RGB, GL_UNSIGNED_BYTE, bb);
А потом дополнительно я убрал EGL_ALPHA_SIZE
у mGL(экземпляр GL10) EGLConfig. И я сдал GLES20.GL_RGB
в качестве параметра внутреннего формата, когда вызывается метод GLUtils.texImage2D().
Однако результат показывает, что что-то не так. Полученное изображение имеет только черный цвет, и при проверке данных bb
буфер после glReadPixels()
вызов метода, я обнаружил, что все данные равны нулю. Мне нужен совет. Помогите, плз.
1 ответ
В ядре GLES2 единственный действующий format
/ type
Комбо для glReadPixels являются:
GL_RGBA
/GL_UNSIGNED_BYTE
- Необязательный специфичный для кадрового буфера
format
/type
запрашивается черезglGetIntegerv
сGL_IMPLEMENTATION_COLOR_READ_FORMAT
а такжеGL_IMPLEMENTATION_COLOR_READ_TYPE
соответственно
В GLES2 без расширений, если GL_IMPLEMENTATION_COLOR_READ_FORMAT
/ GL_IMPLEMENTATION_COLOR_READ_TYPE
не принесите ничего полезного, вы застряли с GL_RGBA
/ GL_UNSIGNED_BYTE
, к несчастью.
С GLES3 вы можете glReadPixels
в границу GL_PACK_BUFFER
, а также glMapBufferRange
что, опять же, вы ограничены format
,
Отмечу, что драйверы склонны к эмуляции тесно упакованных 24-битных форматов rgb8, вместо этого реализуя только лучше выровненные форматы, такие как rgba8, rgb565 и rgba4. Визуализируемый формат, обозначаемый как "rgb8", потенциально просто за кадром rgbx8.
Сильно зависит от драйвера, но если вы не заботитесь о хранении содержимого кадрового буфера, вы можете получить некоторую пропускную способность памяти с помощью EXT_discard_framebuffer. (или же glInvalidateFramebuffer
в GLES3)
Вы также можете заглянуть в EGL_KHR_lock_surface3.