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宽度的百分比
两个用例的输出都来自同一传感器,仅裁剪策略不同,按以下步骤计算:
- 获取两个用例的输出分辨率
// 取Preview输出分辨率 val previewResolution = preview.previewInfo.value?.resolution ?: return // 取ImageCapture输出分辨率 val captureResolution = imageCapture.attachedSurfaceResolution ?: return
- 适配屏幕方向的宽高转换
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
- 计算百分比
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
相关产品推荐
相关产品推荐

