- 作者:老汪软件技巧
- 发表时间: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 效果:
注意代码最后一步,要从裁剪后的 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 中将图像裁剪成不同的形状和方向。
希望这篇文章对你有所帮助,如果你有任何问题或建议,欢迎在评论区留言。