我正在为我的应用程序制作扫描仪,但是当我裁剪图像时,它总是错误地裁剪它。
图像上的裁剪矩形-
裁剪后的图像-
我的裁剪矩形的代码...
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 是一个 View Controller ,我将图像传递到其中 pdfImage 是您在第一张图片中看到的整个图像 croppingRect 是应该没问题的矩形
我真的需要这方面的帮助,我花了过去 2 个小时尝试只裁剪一张图像。
最佳答案
您是否在 ImageView 中使用一种缩放内容模式?如果是这样,图像的尺寸与 ImageView 的尺寸不同,您有两个选择:
您可以在尝试裁剪之前调整图像大小以匹配 ImageView 的尺寸。然后标准的裁剪程序就可以发挥作用。但这可能会导致分辨率下降或出现像素化。
更好的解决方案是在裁剪之前将裁剪矩形转换为图像尺寸的坐标。
例如:
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,这是我使用的裁剪方法,cropped(to:)
from https://stackoverflow.com/a/28513086/1271826 ,使用更现代的 UIGraphicsImageRenderer
,如果可以的话使用 CoreGraphics 裁剪,等等。但是使用您想要的任何裁剪例程,但只需确保将坐标转换为适合图像的坐标即可。
关于swift - 裁剪(至 : CGRect) doesn't crop correctly,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63770562/