微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

裁剪至:CGRect无法正确裁剪

如何解决裁剪至:CGRect无法正确裁剪

我正在为我的应用制作扫描仪,但是当我裁剪图像时,它总是会错误地裁剪。

图像裁剪图-

Image

裁剪后的图像-

Image

我的裁剪矩形代码...

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/1271826cropped(to:),使用更现代的UIGraphicsImageRenderer,如果可以的话,使用CoreGraphics裁剪,依此类推。需要,但只需确保将坐标转换为适合图像的内容即可。

enter image description here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。