swift - 裁剪(至 : CGRect) doesn't crop correctly

标签 swift xcode uiimage crop swift5

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

图像上的裁剪矩形-

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 是一个 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 裁剪,等等。但是使用您想要的任何裁剪例程,但只需确保将坐标转换为适合图像的坐标即可。

enter image description here

关于swift - 裁剪(至 : CGRect) doesn't crop correctly,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63770562/

相关文章:

ios - 在 objc 中使用 swift 框架

arrays - 快速编辑 plist 数组

ios - iOS7无线上网/网络录音怎么访问?

objective-c - 在 Objective-C 中在另一个自定义类中使用自定义类

iphone - 如何将 OpenGL View 捕获为 UIImage?

ios - 尝试以编程方式将 UIScrollView 添加到我的应用程序中,但我不断收到空白 View

ios - Swift:所有 ViewController 的默认 Storyboard背景图像

iOS 查看尺寸 iPad

iphone - iOS:使用 UIBezierPath 屏蔽 UIImage

ios - UIImage imageWithContentsOfFile 中的路径参数 : for XCAsset