• 作者:老汪软件技巧
  • 发表时间:2024-09-07 00:04
  • 浏览量:

前言

在 iOS 和 macOS 开发中,裁剪图像是非常常见的操作,比如在 App 中裁剪用户头像或者裁剪封面图片等。

今天来讲讲如何在 Swift 中裁剪图片。

中心裁剪图片

中心裁剪是指从现有图像中裁剪出一个以图像中心为基础的形状。

实现原理是先计算出宽高中最短的边,然后以中心为锚点,计算出 x 和 y 的偏移量,最后根据偏移量和最短边长计算出裁剪的矩形区域。

中心矩形裁剪代码示例

中心矩形裁剪示例的代码如下,我们给 UIImage 实现一个分类:

extension UIImage {
    func centerCrop() -> UIImage? {
        // 计算最短边的长度
        let sideLength = min(self.size.width, self.size.height)
        // 确定中心正方形的 x 和 y 坐标
        let sourceSize = self.size
        let xOffset = (sourceSize.width - sideLength) / 2.0
        let yOffset = (sourceSize.height - sideLength) / 2.0
        // 定义裁剪矩形
        let cropRect = CGRect(
            x: xOffset,
            y: yOffset,
            width: sideLength,
            height: sideLength
        ).integral
        // 中心裁剪图像
        guard let cgImage = cgImage?.cropping(to: cropRect) else {
            return nil
        }
        return UIImage(cgImage: cgImage, scale: imageRendererFormat.scale, orientation: imageOrientation)
    }
}

在使用的时候,只需要调用 centerCrop() 方法即可:

let image = UIImage(named: "example.jpg")
let croppedImage = image?.centerCrop()

这个可视化示例展示了应用于上述代码的几何操作:

下边是我的 demo 效果:

Swift 开发者必看:如何优雅地裁剪图片_Swift 开发者必看:如何优雅地裁剪图片_

注意代码最后一步,要从裁剪后的 CGImage 中获取 UIImage,需要用到 imageRendererFormat.scale 和 imageOrientation。否则可能导致非预期的效果。

将图片裁剪成圆形

可以使用 UIGraphicsImageRenderer 和 UIBezierPath 在 Swift 中将 UIImage 裁剪成圆形。

首先我们还是给 UIImage 实现一个分类:

extension UIImage {
    func cropToCircle() -> UIImage? {
        // 计算最短边的长度
        let sideLength = min(self.size.width, self.size.height)
        // 确定中心正方形的 x 和 y 坐标
        let sourceSize = self.size
        let xOffset = (sourceSize.width - sideLength) / 2.0
        let yOffset = (sourceSize.height - sideLength) / 2.0
        // 定义裁剪矩形
        let cropRect = CGRect(
            x: xOffset,
            y: yOffset,
            width: sideLength,
            height: sideLength
        ).integral
        // 因为圆形裁剪会产生透明区域,所以将 opaque 设置为 false,确保裁剪后的图像没有背景填充
        let imageRendererFormat = imageRendererFormat
        imageRendererFormat.opaque = false
        // UIGraphicsImageRenderer().image 提供了一个 block 接口,用于在新 UIImage 中绘制
        let circleCroppedImage = UIGraphicsImageRenderer(
            size: cropRect.size,
            format: imageRendererFormat
        ).image { context in
            // drawRect 是从 (0,0) 开始的 cropRect
            let drawRect = CGRect(
                origin: .zero,
                size: cropRect.size
            )
            // 在 UIBezierPath 上调用 addClip 将会裁剪掉 UIBezierPath 外的所有内容
            // 在这种情况下,drawRect 是一个圆形,所以 UIBezierPath 会裁剪掉圆形外的内容
            UIBezierPath(ovalIn: drawRect).addClip()
            // drawImageRect 偏移图像的边界,使得圆形裁剪位于图像的中心
            let drawImageRect = CGRect(
                origin: CGPoint(
                    x: -xOffset,
                    y: -yOffset
                ),
                size: self.size
            )
            // 在圆形裁剪区域内绘制原图
            self.draw(in: drawImageRect)
        }
        return circleCroppedImage
    }
}

使用的时候,只需要调用 cropToCircle() 方法即可:

let image = UIImage(named: "example.jpg")
let croppedImage = image?.cropToCircle()

下边这个可视化示例展示了上述代码是如何将图片裁剪成圆形的:

下图是我的 demo 效果:

总结

通过使用 UIGraphicsImageRenderer、UIBezierPath 和 UIImage,你可以在 Swift 中将图像裁剪成不同的形状和方向。

希望这篇文章对你有所帮助,如果你有任何问题或建议,欢迎在评论区留言。