Swift中如何为裁剪后的图片添加带Alpha渐变的平滑边缘?
Swift实现图片内部裁剪+Alpha渐变平滑边缘
你可以在现有裁剪代码的基础上,通过Core Graphics创建渐变蒙版并与裁剪后的图片合成,实现边缘平滑的效果。核心思路是给裁剪后的图片叠加一个边缘透明、中间不透明的渐变蒙版,利用混合模式让图片边缘呈现渐变透明的平滑过渡。
完整实现代码
首先给UIImage添加扩展方法,方便复用:
extension UIImage { func croppedWithSmoothEdge(to rect: CGRect, edgeBlurRadius: CGFloat = 10) -> UIImage? { // 1. 执行基础裁剪 guard let sourceCGImage = self.cgImage, let croppedCGImage = sourceCGImage.cropping(to: rect) else { return nil } let croppedImage = UIImage(cgImage: croppedCGImage, scale: self.scale, orientation: self.imageOrientation) let outputSize = croppedImage.size // 2. 创建渐变蒙版:边缘透明,中间完全不透明 UIGraphicsBeginImageContextWithOptions(outputSize, false, self.scale) guard let context = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext() return croppedImage } // 定义渐变颜色:从透明到不透明 let colorComponents: [CGFloat] = [0, 0, 0, 0, // 透明 0, 0, 0, 1] // 不透明 guard let gradient = CGGradient(colorSpace: CGColorSpaceCreateDeviceRGB(), colorComponents: colorComponents, locations: [0, 1], count: 2) else { UIGraphicsEndImageContext() return croppedImage } // 清空画布,先绘制中间完全不透明的矩形区域 context.clear(CGRect(origin: .zero, size: outputSize)) let innerRect = CGRect(x: edgeBlurRadius, y: edgeBlurRadius, width: outputSize.width - 2 * edgeBlurRadius, height: outputSize.height - 2 * edgeBlurRadius) context.setFillColor(UIColor(white: 1, alpha: 1).cgColor) context.fill(innerRect) // 绘制四个边缘的渐变过渡 // 顶部渐变 context.drawLinearGradient(gradient, start: CGPoint(x: 0, y: 0), end: CGPoint(x: 0, y: edgeBlurRadius), options: []) // 底部渐变 context.drawLinearGradient(gradient, start: CGPoint(x: 0, y: outputSize.height), end: CGPoint(x: 0, y: outputSize.height - edgeBlurRadius), options: []) // 左侧渐变 context.drawLinearGradient(gradient, start: CGPoint(x: 0, y: 0), end: CGPoint(x: edgeBlurRadius, y: 0), options: []) // 右侧渐变 context.drawLinearGradient(gradient, start: CGPoint(x: outputSize.width, y: 0), end: CGPoint(x: outputSize.width - edgeBlurRadius, y: 0), options: []) guard let maskImage = UIGraphicsGetImageFromCurrentImageContext() else { UIGraphicsEndImageContext() return croppedImage } UIGraphicsEndImageContext() // 3. 将蒙版与裁剪后的图片合成 UIGraphicsBeginImageContextWithOptions(outputSize, false, self.scale) croppedImage.draw(at: .zero) // 使用destinationIn混合模式,蒙版透明区域会让图片对应区域透明 maskImage.draw(at: .zero, blendMode: .destinationIn, alpha: 1) guard let finalImage = UIGraphicsGetImageFromCurrentImageContext() else { UIGraphicsEndImageContext() return croppedImage } UIGraphicsEndImageContext() return finalImage } }
使用示例
替换你原有的裁剪代码,调用扩展方法即可:
private var mInputImage: UIImage = UIImage(named: "example")! let croppingRect = CGRect(x: 0, y: 0, width: 200, height: 200) // edgeBlurRadius控制渐变边缘的宽度,值越大边缘过渡越柔和 if let smoothedCroppedImage = mInputImage.croppedWithSmoothEdge(to: croppingRect, edgeBlurRadius: 15) { // 这里可以使用处理后的带平滑边缘的图片 }
关键说明
edgeBlurRadius参数:调整渐变边缘的宽度,根据实际需求设置,默认10pt- 混合模式
destinationIn:保证蒙版的Alpha通道完全作用于图片,蒙版透明的区域会让图片对应区域也透明,实现平滑边缘效果 - 所有操作都在CGImage层面完成,属于非UI层面的图片处理,符合你的需求
内容的提问来源于stack exchange,提问作者Joya Roy
相关产品推荐
相关产品推荐

