Camera 相机开发
问题
CameraX 和 Camera2 有什么区别?如何实现相机预览和拍照?
答案
CameraX vs Camera2
| 维度 | CameraX | Camera2 |
|---|---|---|
| 抽象层级 | 高(用例驱动) | 低(底层 API) |
| 代码复杂度 | 简单 | 复杂 |
| 生命周期管理 | 自动绑定 | 手动管理 |
| 设备兼容性 | 内部处理差异 | 需自行适配 |
| 扩展能力 | 受限 | 完全控制 |
| 推荐场景 | 大多数应用 | 需要精细控制 |
提示
Google 官方推荐新项目使用 CameraX。Camera2 适合需要手动控制曝光、对焦、帧率等参数的专业相机应用。
CameraX 核心用例
CameraX 拍照示例
class CameraFragment : Fragment() {
private lateinit var cameraProvider: ProcessCameraProvider
private lateinit var imageCapture: ImageCapture
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
startCamera()
}
private fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
cameraProviderFuture.addListener({
cameraProvider = cameraProviderFuture.get()
// 预览用例
val preview = Preview.Builder().build().also {
it.surfaceProvider = binding.previewView.surfaceProvider
}
// 拍照用例
imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build()
// 图像分析用例(如二维码识别)
val imageAnalysis = ImageAnalysis.Builder()
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build()
.also {
it.setAnalyzer(executor) { imageProxy ->
// 处理每一帧
processImage(imageProxy)
imageProxy.close()
}
}
// 绑定到生命周期
cameraProvider.unbindAll()
cameraProvider.bindToLifecycle(
viewLifecycleOwner, // 自动管理生命周期
CameraSelector.DEFAULT_BACK_CAMERA,
preview, imageCapture, imageAnalysis
)
}, ContextCompat.getMainExecutor(requireContext()))
}
private fun takePhoto() {
val outputOptions = ImageCapture.OutputFileOptions.Builder(
File(requireContext().cacheDir, "photo_${System.currentTimeMillis()}.jpg")
).build()
imageCapture.takePicture(
outputOptions,
ContextCompat.getMainExecutor(requireContext()),
object : ImageCapture.OnImageSavedCallback {
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
val uri = output.savedUri
// 拍照成功
}
override fun onError(exception: ImageCaptureException) {
// 拍照失败
}
}
)
}
}
常见面试问题
Q1: CameraX 如何实现人脸检测或二维码识别?
答案:
使用 ImageAnalysis 用例。每一帧通过 Analyzer 回调传入 ImageProxy,可以将其转换为 Bitmap 或 InputImage(ML Kit),然后调用 ML Kit 的人脸检测或条码扫描 API。处理完后必须调用 imageProxy.close() 释放帧。
Q2: Camera2 适合什么场景?
答案:
Camera2 适合需要精细控制相机参数的场景:手动对焦、手动曝光、RAW 格式拍摄、自定义帧率、多摄像头同时打开等。CameraX 底层也是基于 Camera2 实现的,它在 Camera2 之上提供了更友好的 API 和设备兼容性处理。