Android相机框架实战:滤镜相机与实时特效集成方案 - 第3节
3.1 CameraX 架构概览
CameraX 是 Google 推出的 Jetpack 相机库,它在 Camera2 之上封装了一层更易用的 API,同时保留了强大的扩展能力。CameraX 的核心设计理念是 “用例(UseCase)”——开发者只需声明“我要做什么”,而不必关心底层的相机会话管理细节。
核心优势: 生命周期感知、设备兼容性自动处理、用例可组合、支持扩展(如 HDR、美颜)。
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 时,相机自动释放。这彻底避免了手动管理相机打开/关闭的繁琐逻辑。
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 的帧数据处理,为滤镜特效打下基础。