如何在 swift 4 或更高版本中裁剪具有可选区域的图像?

How to crop an image with a selectable area in swift 4 or later?

我需要一些关于我想在我的应用程序中实现的功能的帮助。 我在 Aspect Fit 中有一个带有内容模式的图像视图。当我从我的库中获取图像时,我想用一个可调整的矩形裁剪一个区域来创建一个新图像。 我一直在寻找一些示例或在线教程,但没有成功。 任何人都可以帮我吗? 这是我的视图中的图像。

如果我正确理解你的问题,那么你的问题分为两个部分:

  1. 图像上方的可调整矩形区域
  2. 裁剪 UIImage

打破你的google查询并根据上述问题分别搜索解决方案。

或者可能寻求帮助或使用类似这样的东西:

iOS-Image-Crop-View

简单的解决方案是仅在特定 CGRect:

内渲染图像视图
func snapshot(in imageView: UIImageView, rect: CGRect) -> UIImage {
    return UIGraphicsImageRenderer(bounds: rect).image { _ in
        imageView.drawHierarchy(in: imageView.bounds, afterScreenUpdates: true)
    }
}

该方法的局限性在于,如果图像的分辨率比图像视图可以呈现的分辨率高得多(当我们使用“纵横比比例适合”时通常会出现这种情况),您将失去这种额外的精度。

如果你想保留分辨率,你应该将 CGRect 转换为与图像的坐标,在这种情况下,假设“纵横比比例适合”(即居中和缩放以便显示整个图像):

func snapshot(in imageView: UIImageView, rect: CGRect) -> UIImage {
    assert(imageView.contentMode == .scaleAspectFit)

    let image = imageView.image!

    // figure out what the scale is

    let imageRatio = imageView.bounds.width / imageView.bounds.height
    let imageViewRatio = image.size.width / image.size.height

    let scale: CGFloat
    if imageRatio > imageViewRatio {
        scale = image.size.height / imageView.bounds.height
    } else {
        scale = image.size.width / imageView.bounds.width
    }

    // convert the `rect` into coordinates within the image, itself

    let size = rect.size * scale
    let origin = CGPoint(x: image.size.width  / 2 - (imageView.bounds.midX - rect.minX) * scale,
                         y: image.size.height / 2 - (imageView.bounds.midY - rect.minY) * scale)
    let scaledRect = CGRect(origin: origin, size: size)

    // now render the image and grab the appropriate rectangle within
    // the image’s coordinate system

    let format = UIGraphicsImageRendererFormat()
    format.scale = image.scale
    format.opaque = false

    return UIGraphicsImageRenderer(bounds: scaledRect, format: format).image { _ in
        image.draw(at: .zero)
    }
}

使用此扩展程序:

extension CGSize {
    static func * (lhs: CGSize, rhs: CGFloat) -> CGSize {
        return CGSize(width: lhs.width * rhs, height: lhs.height * rhs)
    }
}

产生: