如何在 android 上通过 glReadPixels() 获取 24 位颜色信息?

How to get 24bit color information by glReadPixels() on 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();
}

之后,为了节省内存和处理时间,为了获得不带 alpha 通道的 24 位颜色信息,我将代码的第 1 行和第 2 行更改如下。

ByteBuffer bb = ByteBuffer.allocate(mWidth * mHeight * 3);
mGL.glReadPixels(0, 0, mWidth, mHeight, GL_RGB, GL_UNSIGNED_BYTE, bb);

此外,我在 mGL(GL10 实例)的 EGLConfig 中删除了 EGL_ALPHA_SIZE。当调用 GLUtils.texImage2D() 方法时,我将 GLES20.GL_RGB 作为内部格式参数传递。

但是,结果表明有问题。结果图像只有黑色,当我在 glReadPixels() 方法调用后检查 bb 缓冲区的数据时,我发现所有数据都是零。我需要建议。请帮忙

在核心 GLES2 中,glReadPixels 的唯一有效 format/type 组合是:

  • GL_RGBA/GL_UNSIGNED_BYTE
  • 通过 glGetIntegerv 分别使用 GL_IMPLEMENTATION_COLOR_READ_FORMATGL_IMPLEMENTATION_COLOR_READ_TYPE 查询的可选帧缓冲区特定 format/type

在没有扩展的 GLES2 中,如果 GL_IMPLEMENTATION_COLOR_READ_FORMAT/GL_IMPLEMENTATION_COLOR_READ_TYPE 没有产生有用的东西,不幸的是,你只能使用 GL_RGBA/GL_UNSIGNED_BYTE

使用 GLES3,您可以 glReadPixels 进入边界 GL_PACK_BUFFER,并且 glMapBufferRange 但是,您再次受到 format 的限制。

我会注意到,驱动程序倾向于模拟紧密压缩的 rgb8 24 位格式,而不是仅实现更好对齐的格式,如 rgba8、rgb565 和 rgba4。公开为 "rgb8" 的可渲染格式在幕后可能只是 rgbx8。

高度依赖驱动程序,但如果您不关心保留帧缓冲区的内容,您可以使用 EXT_discard_framebuffer 赢回一些内存带宽。 (或 GLES3 中的 glInvalidateFramebuffer

您也可以查看 EGL_KHR_lock_surface3