Jetpack Compose中MLKit检测物体后绘制矩形错位问题求助
MLKit物体检测BoundingBox在Compose中绘制错位的解决办法
直接用boundingBox.toComposeRect()出现错位,核心原因是MLKit的坐标系和Compose Canvas的坐标系不匹配:
- MLKit返回的
Rect基于相机捕获的原始图像尺寸(通常是横屏分辨率,比如1920x1080) - Compose Canvas的坐标系基于当前界面的布局尺寸,且竖屏显示时图像还存在旋转适配问题
解决步骤
- 记录预览图像的实际尺寸:在相机预览回调中获取图像的宽高(注意MLKit处理后的图像可能存在旋转,需确认方向)
- 计算适配参数:根据Compose Canvas的尺寸和图像原始尺寸,算出缩放比例、旋转后的坐标偏移
- 转换BoundingBox坐标:将MLKit的原始Rect转换为适配Compose坐标系的Rect
修正后的代码示例
首先定义状态存储图像尺寸和转换后的目标Rect:
// 存储相机预览图像的原始尺寸 var imageSize by remember { mutableStateOf(Size.Zero) } // 存储适配Compose后的Rect var composeRect by remember { mutableStateOf<Rect?>(null) }
在MLKit的成功回调中处理坐标转换(以竖屏显示为例):
.addOnSuccessListener { detectedObjects -> detectedObjects.firstOrNull()?.let { obj -> val originalRect = obj.boundingBox // 竖屏显示时,图像宽高互换,需调整缩放比例 val scaleX = size.width / imageSize.height val scaleY = size.height / imageSize.width // 转换原始坐标到Compose坐标系 val scaledLeft = originalRect.top * scaleX val scaledTop = originalRect.left * scaleY val scaledWidth = originalRect.height() * scaleX val scaledHeight = originalRect.width() * scaleY composeRect = Rect( left = scaledLeft, top = scaledTop, right = scaledLeft + scaledWidth, bottom = scaledTop + scaledHeight ) } }
最后在Canvas中绘制:
if (composeRect != null) { Canvas(modifier = Modifier.fillMaxSize()) { drawRect( color = Color.Black, style = Stroke(3.dp.toPx()), topLeft = composeRect!!.topLeft, size = composeRect!!.size ) } }
关键注意点
- 若为横屏显示,无需互换宽高,直接用
scaleX = size.width / imageSize.width、scaleY = size.height / imageSize.height - 若使用
ImageAnalysis分析图像,可通过imageProxy.imageInfo.rotationDegrees获取图像旋转角度,根据角度调整坐标转换逻辑
内容的提问来源于stack exchange,提问作者APCM
相关产品推荐
相关产品推荐

