2. Android Camera API 演进:Camera1 vs Camera2 vs CameraX,架构对比与选型策略
Android 相机框架自诞生以来经历了三次重大架构迭代:从最初的 Camera1(Android 1.0)到革命性的 Camera2(Android 5.0),再到 Jetpack 生态下的 CameraX(Android 5.0+,通过 Jetpack 扩展)。理解这三代 API 的设计哲学、架构差异和适用场景,是构建高性能滤镜相机与实时特效系统的基石。
2.1 三代 API 核心架构对比
下表从架构模式、线程模型、数据流控制、设备兼容性等关键维度,对 Camera1、Camera2 和 CameraX 进行横向对比:
| 对比维度 | Camera1 | Camera2 | CameraX |
|---|---|---|---|
| 架构模式 | 单体式(Monolithic) | 管道式(Pipeline) | 用例驱动(Use-case) |
| 控制模型 | 回调 + 参数设置 | CaptureRequest + CaptureResult | UseCase + 绑定生命周期 |
| 线程模型 | 单线程回调 | 多线程 + 独立回调 | 内部封装,自动管理 |
| 数据流 | SurfaceView / TextureView | Surface + ImageReader | PreviewView / ImageAnalysis |
| 设备兼容性 | 高(所有设备) | 中(需 Level 3+ 支持) | 高(自动适配 + 厂商扩展) |
| 实时滤镜支持 | 困难(需 Surface 重绘) | 原生支持(YUV_420_888) | 良好(ImageAnalysis + GL) |
| 生命周期管理 | 手动 | 手动 | 自动(Lifecycle 绑定) |
| 推荐场景 | 简单拍照 / 遗留系统 | 专业相机 / 自定义管线 | 快速集成 / 跨版本兼容 |
2.2 Camera1:遗留时代的单体架构
Camera1 是 Android 最早的相机 API,设计上采用 单体式架构:一个 Camera 对象同时负责预览、拍照、参数设置和回调分发。开发者通过 setParameters() 设置曝光、白平衡、对焦等参数,通过 setPreviewCallback() 获取预览帧数据。
onPreviewFrame)返回的 YUV 数据格式因厂商而异(NV21 / YV12 / YUY2),且无法保证帧率稳定。对于需要逐帧处理像素的滤镜相机,这会导致严重的兼容性问题和性能瓶颈。
Camera1 的典型数据流如下:
// Camera1 预览回调(遗留代码示例)
Camera camera = Camera.open();
Camera.Parameters params = camera.getParameters();
params.setPreviewFormat(ImageFormat.NV21); // 常见但非标准
camera.setParameters(params);
camera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// data 格式为 NV21,需手动转换为 RGB 或 YUV_420_888
// 无法保证回调频率与帧率同步
processFrameForFilter(data);
}
});
camera.startPreview();
2.3 Camera2:管道式架构与精细控制
Camera2 在 Android 5.0(API 21)引入,彻底重构了相机框架。其核心是 管道式架构:CameraManager 管理设备,CameraDevice 代表物理相机,CameraCaptureSession 管理数据流管道,CaptureRequest 封装每一帧的配置参数。
Camera2 的关键优势在于:
- 逐帧控制:每个
CaptureRequest可独立设置曝光、增益、白平衡、3A 模式等参数。 - 多路输出:支持同时输出预览 Surface、拍照 ImageReader、YUV_420_888 分析流。
- YUV_420_888 标准化:所有 Camera2 设备必须支持此格式,为 OpenGL ES 滤镜处理提供了统一输入。
- 高速连拍:支持 BURST 模式,帧率可达 30fps+。
ImageReader 配合 YUV_420_888 格式,可以直接将预览帧送入 OpenGL ES 纹理(通过 SurfaceTexture 或 EGLImageKHR),实现零拷贝的 GPU 滤镜处理。
Camera2 的架构关系如下图所示:
2.4 CameraX:用例驱动的 Jetpack 封装
CameraX 是 Google 在 2019 年推出的 Jetpack 相机库,基于 Camera2 封装,但提供了更高级的 用例(UseCase)抽象。开发者不再直接操作 CameraDevice 和 CaptureSession,而是声明 Preview、ImageCapture、ImageAnalysis、VideoCapture 四个用例,由 CameraX 内部协调生命周期、设备适配和会话管理。
CameraX 的核心特性:
- 生命周期感知:自动绑定
LifecycleOwner,在 Activity/Fragment 的 onResume/onPause 时自动开启/关闭相机。 - 设备兼容性:通过
CameraXConfig和厂商扩展(如美颜、HDR)自动适配不同设备。 - 预览视图:
PreviewView封装了 SurfaceView 和 TextureView 的切换逻辑,支持缩放、旋转。 - 分析流:
ImageAnalysis提供 YUV_420_888 格式的帧数据,支持背压策略(非阻塞 / 阻塞)。
ImageAnalysis 返回的 ImageProxy 可以转换为 OpenGL 纹理。不过相比 Camera2 的直接 Surface 绑定,CameraX 多了一层内存拷贝,对极致性能场景(如 60fps 实时滤镜)有一定影响。
CameraX 的用例架构如下图所示:
2.5 选型策略:滤镜相机与实时特效场景
针对本课程的核心目标——滤镜相机与实时特效集成,我们给出以下选型建议:
| 场景需求 | 推荐 API | 理由 |
|---|---|---|
| 快速原型 / MVP 验证 | CameraX | 代码量少,生命周期自动管理,内置 PreviewView |
| 高性能实时滤镜(60fps) | Camera2 | 直接绑定 SurfaceTexture,零拷贝送入 GPU |
| 多路并行输出(预览 + 分析 + 录制) | Camera2 | 原生支持多 Surface 绑定,帧同步精确 |
| 跨版本兼容(Android 5.0 ~ 14) | CameraX | Jetpack 库自动适配厂商差异 |
| 自定义 3A 算法 / 专业摄影 | Camera2 | 逐帧控制曝光、增益、对焦区域 |
| 遗留系统维护(minSdk < 21) | Camera1 | 唯一选择,但需自行处理兼容性 |
2.6 从 Camera1 到 Camera2 的迁移要点
如果你正在维护一个基于 Camera1 的滤镜相机项目,迁移到 Camera2 时需注意以下关键变化:
- 权限模型:Camera2 需要
CAMERA权限,且 Android 6.0+ 需运行时申请。 - 线程模型:Camera2 的所有回调都在独立线程中执行,需自行管理 HandlerThread。
- 参数设置:从
setParameters()改为CaptureRequest.Builder逐帧构建。 - 预览数据:从
onPreviewFrame(byte[])改为ImageReader.OnImageAvailableListener,格式统一为YUV_420_888。 - 状态管理:Camera2 的状态机更复杂,需处理
CameraDevice.StateCallback和CameraCaptureSession.StateCallback。
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL 决定了设备的能力等级(LEGACY / LIMITED / FULL / LEVEL_3)。LEGACY 级别的设备仅支持 Camera1 的功能子集,无法使用 YUV_420_888 多路输出。在迁移前务必检查硬件级别,并准备降级方案。
以下是一个简单的硬件级别检查代码片段:
// 检查 Camera2 硬件支持级别
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
String cameraId = manager.getCameraIdList()[0]; // 通常为 "0"
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
Integer level = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
if (level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
// 降级到 Camera1 或限制功能
Log.w("CameraAPI", "设备仅支持 LEGACY 级别,无法使用高级特性");
} else if (level >= CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL) {
// 支持 FULL 级别,可以使用 YUV_420_888 多路输出
Log.i("CameraAPI", "设备支持 FULL 级别,适合实时滤镜管线");
}
2.7 本章小结
- Camera1 是遗留架构,适合 minSdk < 21 的兼容场景,但无法满足高性能滤镜需求。
- Camera2 是管道式架构,提供逐帧控制和 YUV_420_888 标准化输出,是实时特效管线的首选。
- CameraX 是 Jetpack 封装,简化了生命周期和设备适配,适合快速集成和跨版本兼容。
- 在滤镜相机项目中,推荐以 Camera2 为主力 API,结合 OpenGL ES 实现零拷贝的 GPU 渲染管线。
- 迁移时需注意硬件级别检查、线程模型重构和参数设置方式的改变。