You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android CameraX如何关联Preview预览范围与ImageCapture捕获范围

CameraX 预览区域导出Bitmap与范围匹配方案

方案一:导出Preview当前显示的Bitmap

优先采用PreviewView直接取图的方式,得到的内容和屏幕显示完全一致,无需额外做坐标对齐:

  • 直接调用PreviewView的bitmap属性获取完整预览帧:
// 获取当前预览完整Bitmap
val fullPreviewBitmap = previewView.bitmap ?: return@run
// 裁剪你在界面上框选的矩形区域(selectRect为相对于PreviewView的视图坐标)
val targetBitmap = Bitmap.createBitmap(
    fullPreviewBitmap,
    selectRect.left,
    selectRect.top,
    selectRect.width(),
    selectRect.height()
)

该方案适配所有PreviewView内置的缩放、裁剪、旋转逻辑,不需要绑定额外用例,性能开销最低。

如果需要从原始相机流取图,可绑定ImageAnalysis用例,设置和Preview相同的缩放类型、目标分辨率,在ImageAnalysis.Analyzer回调中把ImageProxy转成Bitmap后,按照Preview的裁剪规则裁剪即可。


方案二:计算Preview显示宽度占ImageCapture宽度的百分比

两个用例的输出都来自同一传感器,仅裁剪策略不同,按以下步骤计算:

  1. 获取两个用例的输出分辨率
// 取Preview输出分辨率
val previewResolution = preview.previewInfo.value?.resolution ?: return
// 取ImageCapture输出分辨率
val captureResolution = imageCapture.attachedSurfaceResolution ?: return
  1. 适配屏幕方向的宽高转换
val isPortrait = resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT
// 竖屏状态下相机输出的宽高需要交换,和显示逻辑对齐
val previewDisplayWidth = if (isPortrait) previewResolution.height else previewResolution.width
val captureDisplayWidth = if (isPortrait) captureResolution.height else captureResolution.width
  1. 计算百分比
val widthPercent = (previewDisplayWidth.toFloat() / captureDisplayWidth.toFloat()) * 100

若两个用例设置了不同的宽高比,需要额外计算裁剪系数:例如Preview设置16:9、ImageCapture设置4:3,默认FILL_CENTER缩放模式下,Preview的显示宽度为ImageCapture宽度的75%。


附加:预览框选区域映射到拍照结果的逻辑

如果需要从ImageCapture拍照得到的大图中裁剪出预览框选的区域,用上面得到的比例换算坐标即可:

  • 换算系数 = captureDisplayWidth / previewView.width
  • 拍照结果中对应区域的left = 框选left * 换算系数
  • 拍照结果中对应区域的top = 框选top * 换算系数
  • 区域宽高同样按换算系数放大即可

内容的提问来源于stack exchange,提问作者ats

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 23:18:01