VNDetectRectangleRequest的Bounding Box在ImageView上绘制位置异常问题
问题原因
- 坐标系不匹配:Vision框架返回的
boundingBox为归一化坐标,原点位于左下角,而Core Graphics绘制UIImage时使用的坐标系原点位于左上角,y轴方向完全相反,未做变换时就会出现y轴整体偏移的问题。 - 变换参数错误:你参考的变换逻辑使用了
imageView.frame的控件尺寸作为变换基准,但drawOnImage方法实际是在原始图片的像素尺寸画布上绘制,当图片实际分辨率和imageView控件尺寸不一致时,变换后的矩形会直接超出画布范围,因此完全不可见。
解决方案
不需要依赖imageView的尺寸,直接基于待绘制的目标图片尺寸做坐标校正即可:
- 极简校正方案(无需矩阵变换,不易出错)
// 先将归一化boundingBox转换为对应图片尺寸的rect(此时还是Vision的左下角坐标系) let visionRect = VNImageRectForNormalizedRect(boundingBox, Int(image.size.width), Int(image.size.height)) // 翻转y轴适配UIKit绘图坐标系 let correctedRect = CGRect( x: visionRect.origin.x, y: image.size.height - visionRect.origin.y - visionRect.size.height, width: visionRect.size.width, height: visionRect.size.height )
将得到的correctedRect传入drawOnImage方法直接绘制即可。
- 矩阵变换实现方案(如果你需要保持变换写法)
注意要将变换基准替换为图片本身的尺寸,而非imageView的控件尺寸:
let scale = CGAffineTransform.identity.scaledBy(x: image.size.width, y: image.size.height) let transform = CGAffineTransform(scaleX: 1, y: -1).translatedBy(x: 0, y: -image.size.height) let transformedRect = boundingBox.applying(scale).applying(transform)
注意:因为你是直接在原始图片上绘制矩形,再赋值给
UIImageView,Scale to Fill的展示模式只会适配整个图片,绘制的矩形会和图片同步适配,不会出现二次错位问题。
内容的提问来源于stack exchange,提问作者Jack Gruber
相关产品推荐
相关产品推荐

