Как получить информацию о 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.

Другие вопросы по тегам