安卓相机使用OpenGLES渲染

安卓相机使用OpenGLES渲染

使用OpenGL ES实现相机滤镜

相机应用通过将SurfaceView作为消费端,相机框架从HAL拿到相机数据帧后会直接将buffer数据送到SurfaceFlinger进程进行预览显示。如果相机应用想做更复杂的滤镜效果,那就不应该使用这种方式,而应该使用SurfaceTexture作为消费端,通过回调获取到相机图像数据,再通过把图像数据作为纹理,由OpenGL ES进一步做渲染处理。在渲染过程中,用户可以通过图像算法自由控制滤镜效果。

比如下面左图中不使用滤镜,右图中使用黑白滤镜,在预览中可以看到不同的效果。

可以通过下面几个关键步骤去实现这种滤镜效果的开发。

关键步骤

使用GLSurfaceView

为了实现OpenGL渲染,需要使用到GLSurfaceView组件,每一个GLSurfaceView只能设置一个Renderer对象,Renderer对象设置时,会启动一个GLThread线程来专门负责渲染工作。

构建GLSurfaceView.Renderer对象

GLSurfaceView.Renderer是定义在GLSurfaceView中的接口,可以创建一个CameraRenderer类实现该接口。

1
2
3
4
5
public interface Renderer {
void onSurfaceCreated(GL10 gl, EGLConfig config);
void onSurfaceChanged(GL10 gl, int width, int height);
void onDrawFrame(GL10 gl);
}

在CameraRenderer的onSurfaceCreated中,做下面几件事。

  1. 创建一个外部纹理对象,记录下纹理ID。
  2. 获取到着色器程序ID。
  3. glUseProgram

在onDrawFrame中,要激活和绑定外部纹理

1
2
3
// active and bind external oes texture
GLES20.glActiveTexture(GL_TEXTURE_EXTERNAL_OES);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mOESTextureId);

构建相机消费者SurfaceTexture

  1. 使用已经创建好的纹理ID来创建SurfaceTexture对象
  2. 之后用这个SurfaceTexture对象作为消费端去获取相机数据。

案例

可以查看medianeo工程中的case_opengles



关注博客或微信搜索公众号多媒体与图形,获取更多内容,欢迎在公众号留言交流!
扫一扫关注公众号
作者

占航

发布于

2022-03-06

更新于

2023-10-04

许可协议

评论