我发现了以下问题,但不幸的是其他帖子没有帮助我找到可行的解决方案。
我有一个简单的应用程序,显示相机预览(AVCaptureVideoPreviewLayer),其中视频重力已设置为resizeAspectFill (videoGravity = .resizeAspectFill
)。
据我所知,这只会将图像在宽度上拉伸以填充屏幕。
在我的预览层上,我还应用了一个CGRect作为掩码,具有固定的x、y、宽度和高度。
现在一旦我拍照,我就尝试从图像中剪切出确切的矩形。根据我的理解,我应该使用某种数学方法将CGRect转换为与从AVCapturePhotoOutput方法获取的图像具有相同纵横比的形状,但它似乎在宽度上无法正确裁剪。
private func cropImage(image: UIImage) {
let rect = CGRect(x: 25, y: 150, width: 325, height: 230)
let scale = CGAffineTransform(scaleX: 1/self.view.frame.width, y: 1/self.view.frame.height)
let flip = CGAffineTransform(scaleX: 1, y: -1).translatedBy(x: 0, y: -1)
let bounds = rect.applying(scale).applying(flip)
let topLeft = bounds.topLeft.scaled(to: image.size)
let topRight = bounds.topRight.scaled(to: image.size)
let bottomLeft = bounds.bottomLeft.scaled(to: image.size)
let bottomRight = bounds.bottomRight.scaled(to: image.size)
var ciImage = CIImage(image: image.forceSameOrientation())!
ciImage = ciImage.applyingFilter("CIPerspectiveCorrection", parameters: [
"inputTopLeft": CIVector(cgPoint: bottomLeft),
"inputTopRight": CIVector(cgPoint: bottomRight),
"inputBottomLeft": CIVector(cgPoint: topLeft),
"inputBottomRight": CIVector(cgPoint: topRight)
])
let context = CIContext()
let cgImage = context.createCGImage(ciImage, from: ciImage.extent)
let output = UIImage(cgImage: cgImage!)
let vc = PreviewViewController()
vc.imageView.image = output
self.present(vc, animated: true, completion: nil)
}
所以,基本上它在正确的高度进行裁剪,但只有宽度似乎不太好。
图像示例,我想要捕获的内容。
如您所见,在左上角的边界框停在“Q”按钮后面。
结果:
从这张图片中可以看到,它在高度上确实进行了正确的裁剪,但是如果我们看一下左上角,它也包括在“Q”(Tab 按钮)左侧的按钮的一半。
任何对解决方案的帮助将不胜感激!