如何解决裁剪至:CGRect无法正确裁剪
我正在为我的应用制作扫描仪,但是当我裁剪图像时,它总是会错误地裁剪。
图像裁剪图-
裁剪后的图像-
我的裁剪矩形代码...
func croppedImage(rect: CGRect) -> UIImage {
print("rect: \(rect)")
UIGraphicsBeginImageContextWithOptions(rect.size,false,self.scale)
let context = UIGraphicsGetCurrentContext()! as CGContext
let drawRect : CGRect = CGRect(x: -rect.origin.x,y: -rect.origin.y,width: self.size.width,height: self.size.height)
context.clip(to: CGRect(x:0,y:0,width: rect.size.width,height: rect.size.height))
self.draw(in: drawRect)
let croppedImage = UIGraphicsGetimageFromCurrentimageContext()!
UIGraphicsEndImageContext()
return croppedImage
}
我尝试了无数不同的代码片段来使图像正确裁剪,并且它们都得到相同的结果。
docVC.croppedImage = pdfImage.croppedImage(rect: croppingRect)
docVC是一个视图控制器,我将图像传递到其中 pdfImage是您在第一张图片中看到的整个图像 roppingRect是矩形,应该很好
我真的需要帮助,最近2个小时我一直试图只裁剪一张图像。
解决方法
您是否在图像视图中使用一种缩放内容模式?如果是这样,则图像的尺寸与图像视图的尺寸不同,您有两个选择:
-
您可以在尝试裁剪之前调整图像大小以匹配图像视图的尺寸。然后,将执行标准的裁剪例程。但这可能会导致分辨率下降或像素化。
-
更好的解决方案是在裁剪之前将裁剪矩形转换为图像尺寸的坐标。
例如:
extension UIImageView {
func image(at rect: CGRect) -> UIImage? {
guard
let image = image,let rect = convertToImageCoordinates(rect)
else {
return nil
}
return image.cropped(to: rect)
}
func convertToImageCoordinates(_ rect: CGRect) -> CGRect? {
guard let image = image else { return nil }
let imageSize = CGSize(width: image.size.width,height: image.size.height)
let imageCenter = CGPoint(x: imageSize.width / 2,y: imageSize.height / 2)
let imageViewRatio = bounds.width / bounds.height
let imageRatio = imageSize.width / imageSize.height
let scale: CGPoint
switch contentMode {
case .scaleToFill:
scale = CGPoint(x: imageSize.width / bounds.width,y: imageSize.height / bounds.height)
case .scaleAspectFit:
let value: CGFloat
if imageRatio < imageViewRatio {
value = imageSize.height / bounds.height
} else {
value = imageSize.width / bounds.width
}
scale = CGPoint(x: value,y: value)
case .scaleAspectFill:
let value: CGFloat
if imageRatio > imageViewRatio {
value = imageSize.height / bounds.height
} else {
value = imageSize.width / bounds.width
}
scale = CGPoint(x: value,y: value)
case .center:
scale = CGPoint(x: 1,y: 1)
// unhandled cases include
// case .redraw:
// case .top:
// case .bottom:
// case .left:
// case .right:
// case .topLeft:
// case .topRight:
// case .bottomLeft:
// case .bottomRight:
default:
fatalError("Unexpected contentMode")
}
var rect = rect
if rect.width < 0 {
rect.origin.x += rect.width
rect.size.width = -rect.width
}
if rect.height < 0 {
rect.origin.y += rect.height
rect.size.height = -rect.height
}
return CGRect(x: (rect.minX - bounds.midX) * scale.x + imageCenter.x,y: (rect.minY - bounds.midY) * scale.y + imageCenter.y,width: rect.width * scale.x,height: rect.height * scale.y)
}
}
现在,我只处理四种可能的内容模式,如果您想处理更多的内容模式,则必须自己实现。但是希望这可以说明这种模式,即在尝试裁剪之前将选择CGRect
转换为图像内的坐标。
FWIW,这是我使用的裁剪方法,来自https://stackoverflow.com/a/28513086/1271826的cropped(to:)
,使用更现代的UIGraphicsImageRenderer
,如果可以的话,使用CoreGraphics裁剪,依此类推。需要,但只需确保将坐标转换为适合图像的内容即可。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。