Android CameraX使用

发布于:2025-07-17 ⋅ 阅读:(15) ⋅ 点赞:(0)

一、CameraX 核心组件逻辑关系

1. 组件关系与数据流

2. 组件协作流程

  1. 初始化ProcessCameraProvider 获取相机系统服务

  2. 配置:创建 CameraSelector 选择摄像头

  3. 用例绑定:将 PreviewImageCapture 等用例绑定到生命周期

  4. 预览显示Preview 输出到 PreviewView

  5. 用户交互:通过 CameraControl 控制设备

  6. 拍摄处理ImageCapture 捕获图像并处理

  7. 资源释放:生命周期结束时自动释放资源

二、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 展开,它负责:

  1. 通过 CameraSelector 选择物理摄像头

  2. 将 PreviewImageCaptureImageAnalysis 用例绑定到 LifecycleOwner

  3. 通过 CameraControl 接收用户交互指令

关键参数:

  • bindToLifecycle():接收生命周期所有者、摄像头选择器和用例列表

  • Preview.setSurfaceProvider():连接 PreviewView 显示预览

  • ImageCapture.takePicture():接收输出配置、执行器和回调"

2. 拍摄质量优化策略

"优化 ImageCapture 质量的三大策略:

  1. 模式选择

    • CAPTURE_MODE_MINIMIZE_LATENCY(速度优先,延迟<300ms)

    • CAPTURE_MODE_MAXIMIZE_QUALITY(质量优先,默认)

    • API: ImageCapture.Builder().setCaptureMode()

  2. 参数调优

    • setJpegQuality(85):平衡质量与处理时间

    • setTargetResolution(Size(1080, 1920)):控制处理分辨率

    • setMaxCaptureStages(2):限制处理流水线深度

  3. 高级控制

    • 自定义 CaptureProcess 处理流水线

    • 使用 YUV_420_888 格式减少格式转换

    • 启用硬件加速编码"

3. 手动对焦实现原理

"手动对焦实现四步流程:

  1. 坐标转换

    • 使用 SurfaceOrientedMeteringPointFactory 将触摸坐标转换为对焦点

    • API: createPoint(x, y) 基于 PreviewView 尺寸

  2. 构建对焦动作

    FocusMeteringAction.Builder(point)
        .addPoint(point, FLAG_AF or FLAG_AE) // 对焦+测光
        .setAutoCancelDuration(3, SECONDS)   // 自动重置
  3. 执行控制

    • 通过 CameraControl.startFocusAndMetering() 发送指令

    • 返回 ListenableFuture<FocusMeteringResult>

  4. 状态反馈

    • 监听 cameraInfo.focusState LiveData

    • 处理 Focusing/Focused/Unfocused 状态

    • UI 层实时显示对焦指示器"


网站公告

今日签到

点亮在社区的每一天
去签到