跳到主要内容

Camera 相机开发

问题

CameraX 和 Camera2 有什么区别?如何实现相机预览和拍照?

答案

CameraX vs Camera2

维度CameraXCamera2
抽象层级高(用例驱动)低(底层 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,可以将其转换为 BitmapInputImage(ML Kit),然后调用 ML Kit 的人脸检测或条码扫描 API。处理完后必须调用 imageProxy.close() 释放帧。

Q2: Camera2 适合什么场景?

答案

Camera2 适合需要精细控制相机参数的场景:手动对焦、手动曝光、RAW 格式拍摄、自定义帧率、多摄像头同时打开等。CameraX 底层也是基于 Camera2 实现的,它在 Camera2 之上提供了更友好的 API 和设备兼容性处理。

相关链接