如何在 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_FORMAT
和 GL_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。
为了保存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_FORMAT
和GL_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。