一、CameraX 核心组件逻辑关系
1. 组件关系与数据流
2. 组件协作流程
初始化:
ProcessCameraProvider
获取相机系统服务配置:创建
CameraSelector
选择摄像头用例绑定:将
Preview
、ImageCapture
等用例绑定到生命周期预览显示:
Preview
输出到PreviewView
用户交互:通过
CameraControl
控制设备拍摄处理:
ImageCapture
捕获图像并处理资源释放:生命周期结束时自动释放资源
二、Preview 视频流预览详解
1. 核心 API 参数说明
API | 参数 | 类型 | 说明 |
---|---|---|---|
Preview.Builder() |
- | - | 创建预览用例构建器 |
.setTargetAspectRatio() |
ratio | AspectRatio.RATIO_* |
设置宽高比(4:3/16:9) |
.setTargetRotation() |
rotation | Surface.ROTATION_* |
设置显示旋转方向 |
.build() |
- | - | 构建Preview实例 |
setSurfaceProvider() |
provider | SurfaceProvider |
设置预览表面提供者 |
2. 完整使用流程
// 1. 获取相机提供者
val cameraProviderFuture = ProcessCameraProvider.getInstance(context)
cameraProviderFuture.addListener({
// 2. 获取CameraProvider实例
val cameraProvider = cameraProviderFuture.get()
// 3. 创建预览用例
val preview = Preview.Builder()
.setTargetAspectRatio(AspectRatio.RATIO_16_9) // 设置16:9比例
.setTargetRotation(Surface.ROTATION_0) // 设置旋转方向
.build()
// 4. 设置预览输出
preview.setSurfaceProvider(previewView.surfaceProvider)
// 5. 选择摄像头(后置)
val cameraSelector = CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build()
try {
// 6. 绑定到生命周期
cameraProvider.bindToLifecycle(
this as LifecycleOwner, // 生命周期所有者
cameraSelector, // 摄像头选择器
preview // 预览用例
)
} catch (e: Exception) {
Log.e(TAG, "绑定失败: ${e.message}")
}
}, ContextCompat.getMainExecutor(context))
3. PreviewView 配置参数
<androidx.camera.view.PreviewView
android:id="@+id/previewView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:scaleType="fitCenter" <!-- 缩放类型:fitCenter/fillCenter -->
app:implementationMode="performance" <!-- 性能模式:performance/compatibility -->
/>
三、ImageCapture 图片拍摄详解
1. 核心 API 参数说明
API | 参数 | 类型 | 说明 |
---|---|---|---|
ImageCapture.Builder() |
- | - | 创建拍摄用例构建器 |
.setCaptureMode() |
mode | CAPTURE_MODE_* |
拍摄模式(质量/速度优先) |
.setFlashMode() |
mode | FLASH_MODE_* |
闪光灯模式 |
.setTargetRotation() |
rotation | Surface.ROTATION_* |
图像旋转方向 |
.setJpegQuality() |
quality | Int(1-100) |
JPEG压缩质量 |
takePicture() |
options | OutputFileOptions |
文件输出配置 |
2. 完整拍摄流程
// 1. 创建拍摄用例
val imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY) // 质量优先
.setFlashMode(ImageCapture.FLASH_MODE_AUTO) // 自动闪光灯
.setJpegQuality(95) // JPEG质量95%
.build()
// 2. 绑定到生命周期(与Preview一起)
cameraProvider.bindToLifecycle(
lifecycleOwner,
cameraSelector,
preview,
imageCapture // 添加拍摄用例
)
// 3. 拍摄照片
fun captureImage() {
// 创建输出文件
val photoFile = File(externalMediaDirs.first(), "${System.currentTimeMillis()}.jpg")
// 配置输出选项
val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile)
.setMetadata(ImageCapture.Metadata().apply {
// 设置地理位置信息
location = lastKnownLocation
})
.build()
// 执行拍摄
imageCapture.takePicture(
outputOptions,
ContextCompat.getMainExecutor(context),
object : ImageCapture.OnImageSavedCallback {
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
// 拍摄成功处理
val savedUri = output.savedUri ?: Uri.fromFile(photoFile)
showPreview(savedUri)
}
override fun onError(ex: ImageCaptureException) {
// 错误处理
Log.e(TAG, "拍摄失败: ${ex.message}", ex)
}
}
)
}
四、ImageCapture 质量优化策略
1. 优化参数对比表
优化维度 | API | 推荐值 | 优化效果 | 副作用 |
---|---|---|---|---|
拍摄模式 | setCaptureMode() |
CAPTURE_MODE_MINIMIZE_LATENCY |
延迟降低20-40ms | 图像质量轻微下降 |
图像质量 | setJpegQuality() |
80-90 | 处理时间减少30-50ms | 可能出现压缩伪影 |
分辨率 | setTargetResolution() |
Size(1080, 1920) | 内存占用减少30% | 细节损失 |
缓冲策略 | setMaxCaptureStages() |
2-3 | 内存占用优化 | 可能增加延迟 |
格式选择 | setCaptureProcess() |
自定义处理 | 灵活优化 | 实现复杂 |
2. 高级优化配置
val imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY) // 速度优先
.setJpegQuality(85) // 平衡质量与速度
.setTargetResolution(Size(1080, 1920)) // 全高清分辨率
.setMaxCaptureStages(2) // 限制处理阶段
.setBufferFormat(ImageFormat.JPEG) // 指定输出格式
.apply {
// 高级:自定义图像处理管道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
setCaptureProcess(object : ImageCapture.CaptureProcess {
override fun process(request: ImageCaptureRequest) {
// 实现自定义处理逻辑
}
})
}
}
.build()
五、手动对焦实现详解
1. 对焦相关 API
类 | 方法 | 参数 | 说明 |
---|---|---|---|
CameraControl |
startFocusAndMetering() |
FocusMeteringAction |
启动对焦测光 |
cancelFocusAndMetering() |
- | 取消对焦 | |
setLinearZoom() |
zoom(0.0-1.0) | 线性变焦 | |
FocusMeteringAction |
.Builder() |
MeteringPoint |
创建对焦动作 |
.addPoint() |
point, mode | 添加对焦点 | |
.setAutoCancelDuration() |
time, unit | 自动取消时间 |
2. 手动对焦完整实现
// 1. 获取相机控制对象
val cameraControl = camera.cameraControl
// 2. 创建测光点工厂(基于预览视图)
val meteringPointFactory = SurfaceOrientedMeteringPointFactory(
previewView.width.toFloat(),
previewView.height.toFloat()
)
// 3. 设置触摸监听
previewView.setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
// 4. 创建对焦点(基于触摸位置)
val point = meteringPointFactory.createPoint(event.x, event.y)
// 5. 构建对焦动作
val action = FocusMeteringAction.Builder(point)
.addPoint(point, FocusMeteringAction.FLAG_AF) // 自动对焦
.addPoint(point, FocusMeteringAction.FLAG_AE) // 自动曝光
.setAutoCancelDuration(3, TimeUnit.SECONDS) // 3秒后重置
.build()
// 6. 执行对焦
cameraControl.startFocusAndMetering(action).apply {
addListener({
try {
// 7. 处理对焦结果
val result = get()
when (result?.isFocusSuccessful) {
true -> showFocusSuccess(event.x, event.y)
false -> showFocusFailed(event.x, event.y)
}
} catch (e: Exception) {
Log.e(TAG, "对焦失败: ${e.message}")
}
}, ContextCompat.getMainExecutor(context))
}
}
true
}
// 8. 对焦指示器UI反馈
fun showFocusSuccess(x: Float, y: Float) {
// 显示对焦成功图标
focusIndicator.setImageResource(R.drawable.ic_focus_success)
focusIndicator.x = x - focusIndicator.width / 2
focusIndicator.y = y - focusIndicator.height / 2
focusIndicator.visibility = View.VISIBLE
}
3. 对焦状态处理
// 监听对焦状态变化
camera.cameraInfo.focusState.observe(this) { state ->
when (state) {
is FocusState.Focusing -> showFocusing()
is FocusState.Focused -> showFocused()
is FocusState.Unfocused -> showUnfocused()
}
}
六、总结
1. CameraX 核心组件关系
"CameraX 的核心架构围绕
ProcessCameraProvider
展开,它负责:
通过
CameraSelector
选择物理摄像头将
Preview
、ImageCapture
、ImageAnalysis
用例绑定到LifecycleOwner
通过
CameraControl
接收用户交互指令关键参数:
bindToLifecycle()
:接收生命周期所有者、摄像头选择器和用例列表
Preview.setSurfaceProvider()
:连接PreviewView
显示预览
ImageCapture.takePicture()
:接收输出配置、执行器和回调"
2. 拍摄质量优化策略
"优化 ImageCapture 质量的三大策略:
模式选择:
CAPTURE_MODE_MINIMIZE_LATENCY
(速度优先,延迟<300ms)
CAPTURE_MODE_MAXIMIZE_QUALITY
(质量优先,默认)API:
ImageCapture.Builder().setCaptureMode()
参数调优:
setJpegQuality(85)
:平衡质量与处理时间
setTargetResolution(Size(1080, 1920))
:控制处理分辨率
setMaxCaptureStages(2)
:限制处理流水线深度高级控制:
自定义
CaptureProcess
处理流水线使用
YUV_420_888
格式减少格式转换启用硬件加速编码"
3. 手动对焦实现原理
"手动对焦实现四步流程:
坐标转换:
使用
SurfaceOrientedMeteringPointFactory
将触摸坐标转换为对焦点API:
createPoint(x, y)
基于PreviewView
尺寸构建对焦动作:
FocusMeteringAction.Builder(point) .addPoint(point, FLAG_AF or FLAG_AE) // 对焦+测光 .setAutoCancelDuration(3, SECONDS) // 自动重置
执行控制:
通过
CameraControl.startFocusAndMetering()
发送指令返回
ListenableFuture<FocusMeteringResult>
状态反馈:
监听
cameraInfo.focusState
LiveData处理 Focusing/Focused/Unfocused 状态
UI 层实时显示对焦指示器"