Android相机框架实战:滤镜相机与实时特效集成方案 - 第3节

3.1 CameraX 架构概览

CameraX 是 Google 推出的 Jetpack 相机库,它在 Camera2 之上封装了一层更易用的 API,同时保留了强大的扩展能力。CameraX 的核心设计理念是 “用例(UseCase)”——开发者只需声明“我要做什么”,而不必关心底层的相机会话管理细节。

核心优势: 生命周期感知、设备兼容性自动处理、用例可组合、支持扩展(如 HDR、美颜)。
CameraX 核心架构图 CameraX 核心架构图 Android 应用(Activity / Fragment) ProcessCameraProvider + LifecycleOwner CameraX UseCases(用例) Preview(预览) ImageCapture(拍照) ImageAnalysis(分析) Camera2 / HAL 层

3.2 三大核心用例详解

CameraX 提供了三个开箱即用的核心用例,它们可以单独使用,也可以组合使用。下表对比了它们的职责与典型场景:

用例 职责 输出数据类型 典型场景
Preview 将相机画面实时显示到 Surface / TextureView Surface 取景器、扫码预览
ImageCapture 拍摄高分辨率照片并保存为文件或 Bitmap ImageProxy / File / Bitmap 拍照、连拍、文档扫描
ImageAnalysis 逐帧获取 YUV_420_888 图像数据用于分析 ImageProxy(YUV_420_888) 人脸检测、二维码识别、滤镜实时处理
💡 组合提示: 滤镜相机通常需要同时绑定 Preview(显示画面)和 ImageAnalysis(逐帧处理像素),拍照时再触发 ImageCapture。三者可以共存于同一个相机生命周期中。

3.3 生命周期绑定:自动管理相机资源

CameraX 通过 ProcessCameraProvider 与 LifecycleOwner 实现自动绑定。当 Activity 或 Fragment 进入 onResume 时,相机自动打开;进入 onPause 时,相机自动释放。这彻底避免了手动管理相机打开/关闭的繁琐逻辑。

CameraX 生命周期绑定流程 CameraX 生命周期绑定流程 LifecycleOwner ProcessCameraProvider Camera 生命周期事件自动映射 onResume → 相机打开并绑定用例 onPause → 相机释放,资源自动回收

3.4 用例配置与绑定实战

下面是一个完整的 CameraX 初始化代码片段,展示了如何获取 ProcessCameraProvider、创建三个核心用例并绑定到生命周期:

// 1. 获取 ProcessCameraProvider(异步)
val cameraProviderFuture = ProcessCameraProvider.getInstance(context)
cameraProviderFuture.addListener({
    val cameraProvider = cameraProviderFuture.get()

    // 2. 创建 Preview 用例
    val preview = Preview.Builder()
        .setTargetResolution(Size(1920, 1080))
        .build()
    preview.setSurfaceProvider(surfaceProvider) // 绑定到 TextureView/SurfaceView

    // 3. 创建 ImageCapture 用例
    val imageCapture = ImageCapture.Builder()
        .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
        .build()

    // 4. 创建 ImageAnalysis 用例(用于滤镜处理)
    val imageAnalysis = ImageAnalysis.Builder()
        .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
        .setTargetResolution(Size(1280, 720))
        .build()
    imageAnalysis.setAnalyzer(executor, { imageProxy ->
        // 在这里处理每一帧图像数据
        // imageProxy.image 为 YUV_420_888 格式
        processFrame(imageProxy)
    })

    // 5. 绑定到生命周期
    val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
    cameraProvider.bindToLifecycle(
        lifecycleOwner,      // Activity/Fragment
        cameraSelector,
        preview,
        imageCapture,
        imageAnalysis
    )
}, ContextCompat.getMainExecutor(context))
⚠️ 重要提醒: bindToLifecycle() 方法会返回一个 Camera 对象,你可以通过它获取 CameraInfo(如闪光灯状态、变焦范围)和 CameraControl(如变焦、曝光补偿)。注意:不要在 onPause 后继续持有 Camera 引用。

3.5 用例组合与冲突处理

当多个用例同时绑定时,CameraX 会自动协商分辨率、帧率和输出格式。下表列出了常见组合及其注意事项:

组合 是否支持 注意事项
Preview + ImageCapture ✅ 完全支持 预览和拍照共享同一相机会话,拍照时预览不会中断
Preview + ImageAnalysis ✅ 完全支持 分析帧率受预览帧率限制,建议设置 STRATEGY_KEEP_ONLY_LATEST
Preview + ImageCapture + ImageAnalysis ✅ 完全支持 三个用例共存时,分辨率取所有用例的最大值,注意性能开销
ImageCapture + ImageAnalysis(无 Preview) ⚠️ 部分支持 部分设备不允许无预览时拍照,建议始终绑定 Preview
🎯 滤镜相机最佳实践: 始终绑定 Preview + ImageAnalysis + ImageCapture 三件套。Preview 用于显示实时滤镜效果,ImageAnalysis 用于逐帧处理像素,ImageCapture 用于保存最终照片。三者分辨率可以不同:预览用 1920x1080,分析用 1280x720 以降低计算负载。

3.6 本章小结

  • CameraX 通过 用例(UseCase) 抽象了相机功能,开发者只需声明需求。
  • Preview 负责显示画面,ImageCapture 负责拍照,ImageAnalysis 负责逐帧分析。
  • 生命周期绑定 通过 ProcessCameraProvider.bindToLifecycle() 自动管理相机资源。
  • 三个用例可以同时绑定,CameraX 会自动协调分辨率与帧率。
  • 下一章将深入 ImageAnalysis 的帧数据处理,为滤镜特效打下基础。