You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CameraX 1.3-beta01中使用CameraEffect实现录像特效?

使用CameraX 1.3-beta01的CameraEffect实现录像特效

CameraX 1.3-beta01新增的CameraEffect类支持为录像添加基于OpenGL的特效,以下是具体实现步骤:

1. 自定义CameraEffect子类(核心逻辑)

你需要继承CameraEffect并指定TARGET_VIDEO_CAPTURE目标,然后在关键生命周期方法中管理OpenGL资源,在onDrawFrame中实现特效逻辑。以灰度滤镜为例:

class GrayScaleEffect : CameraEffect(TARGET_VIDEO_CAPTURE) {
    private var glProgram: Int = 0
    private var positionHandle: Int = 0
    private var textureHandle: Int = 0

    override fun onAttach(context: Context, cameraInfo: CameraInfo) {
        // 初始化OpenGL着色器程序
        val vertexShader = """
            attribute vec4 aPosition;
            attribute vec2 aTextureCoord;
            varying vec2 vTextureCoord;
            void main() {
                gl_Position = aPosition;
                vTextureCoord = aTextureCoord;
            }
        """.trimIndent()

        val fragmentShader = """
            precision mediump float;
            varying vec2 vTextureCoord;
            uniform sampler2D uTexture;
            void main() {
                vec4 color = texture2D(uTexture, vTextureCoord);
                float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
                gl_FragColor = vec4(gray, gray, gray, color.a);
            }
        """.trimIndent()

        glProgram = createGlProgram(vertexShader, fragmentShader)
        positionHandle = GLES20.glGetAttribLocation(glProgram, "aPosition")
        textureHandle = GLES20.glGetUniformLocation(glProgram, "uTexture")
    }

    override fun onDetach(context: Context) {
        // 释放OpenGL资源,避免内存泄漏
        GLES20.glDeleteProgram(glProgram)
    }

    override fun onDrawFrame(frame: Frame) {
        // 绑定输入纹理(CameraX传递的摄像头帧数据)
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0)
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, frame.texture)

        // 使用自定义着色器程序
        GLES20.glUseProgram(glProgram)

        // 设置顶点坐标(CameraX提供默认的全屏顶点数组)
        GLES20.glEnableVertexAttribArray(positionHandle)
        GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 0, frame.vertexArray)

        // 传递纹理采样器参数
        GLES20.glUniform1i(textureHandle, 0)

        // 绘制处理后的帧
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4)

        // 解绑资源
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0)
        GLES20.glDisableVertexAttribArray(positionHandle)
    }

    // 辅助方法:创建并链接OpenGL程序
    private fun createGlProgram(vertexShader: String, fragmentShader: String): Int {
        val vertex = loadShader(GLES20.GL_VERTEX_SHADER, vertexShader)
        val fragment = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShader)
        val program = GLES20.glCreateProgram()
        GLES20.glAttachShader(program, vertex)
        GLES20.glAttachShader(program, fragment)
        GLES20.glLinkProgram(program)
        // 可添加链接状态检查,排查程序创建失败问题
        return program
    }

    // 辅助方法:加载并编译着色器
    private fun loadShader(type: Int, shaderCode: String): Int {
        val shader = GLES20.glCreateShader(type)
        GLES20.glShaderSource(shader, shaderCode)
        GLES20.glCompileShader(shader)
        // 可添加编译状态检查,排查着色器语法错误
        return shader
    }
}

2. 将特效绑定到VideoCapture

创建VideoCapture实例后,通过VideoCapture.withEffects()方法将自定义特效绑定,再关联到CameraX的生命周期:

// 初始化默认VideoCapture实例
val videoCapture = VideoCapture.Builder.DEFAULT.build()

// 实例化自定义特效
val grayScaleEffect = GrayScaleEffect()

// 选择后置摄像头
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

// 绑定生命周期与CameraX用例,添加特效
cameraProvider.bindToLifecycle(
    lifecycleOwner,
    cameraSelector,
    VideoCapture.withEffects(videoCapture, listOf(grayScaleEffect))
)

3. 关键注意事项

  • 权限要求:必须申请CAMERA和RECORD_AUDIO运行时权限,否则无法启动录像。
  • OpenGL版本:CameraEffect基于GLES 2.0,确保设备支持该版本(绝大多数现代Android设备都满足)。
  • 性能优化:复杂的着色器逻辑可能降低录像帧率,建议在目标设备上测试,必要时简化Shader代码或使用硬件加速优化。
  • Frame数据使用:Frame类提供的texture(输入纹理ID)、vertexArray(顶点坐标)、textureCoordArray(纹理坐标)是处理帧的核心数据,无需自行生成。

内容的提问来源于stack exchange,提问作者Buntupana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 12:54:56