You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在UIKit实现SwiftUI式向外模糊?解决CIGaussianBlur内缩问题

在UIKit中实现SwiftUI风格的向外模糊效果

使用CIGaussianBlur处理图片时,UIImageView会呈现从边框向内模糊、图像收缩的效果;而SwiftUI中调用.blur()方法是从边框向外模糊的表现。如果想在UIKit里复刻后者的效果,直接使用CIAffineClamp会让模糊在边框处停止,无法满足需求。

解决方案思路

要实现向外模糊,核心是先给原图片添加与模糊半径相等的扩展边距,将图片边缘像素向外延展(匹配SwiftUI模糊的边缘处理逻辑),再应用高斯模糊,最后裁剪回原图片尺寸。这样模糊效果会向外扩散,而非向内收缩。

完整代码实现

private let context = CIContext()
private let blurFilter = CIFilter(name: "CIGaussianBlur")!
private let clampFilter = CIFilter(name: "CIAffineClamp")!

private func createOutwardBlurredImage(using image: UIImage, blurRadius: CGFloat) -> UIImage? {
    guard let inputImage = CIImage(image: image) else { return nil }
    
    // 根据模糊半径扩展图像范围,为向外模糊预留空间
    let extendDistance = blurRadius
    let extendedExtent = inputImage.extent.insetBy(dx: -extendDistance, dy: -extendDistance)
    
    // 用CIAffineClamp延展图像边缘像素,避免模糊时边缘出现收缩或透明
    clampFilter.setValue(inputImage, forKey: kCIInputImageKey)
    clampFilter.setValue(CGAffineTransform.identity, forKey: kCIInputTransformKey)
    guard let clampedImage = clampFilter.outputImage?.cropped(to: extendedExtent) else { return nil }
    
    // 应用高斯模糊
    blurFilter.setValue(clampedImage, forKey: kCIInputImageKey)
    blurFilter.setValue(blurRadius, forKey: kCIInputRadiusKey)
    guard let blurredImage = blurFilter.outputImage else { return nil }
    
    // 裁剪回原图像尺寸,得到向外模糊的最终效果
    guard let cgImage = context.createCGImage(blurredImage, from: inputImage.extent) else { return nil }
    
    return UIImage(cgImage: cgImage)
}

代码关键点说明

  • 扩展图像范围:通过insetBy传入负数,将图像的上下左右边界向外扩展,扩展距离等于模糊半径,确保模糊效果有足够空间向外扩散。
  • 边缘像素延展:CIAffineClamp会把图像边缘的像素向外复制填充,这样在模糊时,边缘区域不会因为没有像素来源而出现收缩或变黑。
  • 裁剪回原尺寸:模糊完成后裁剪回原图像的extent,保证最终输出的图片大小和原图一致,但带有向外扩散的模糊效果。

内容的提问来源于stack exchange,提问作者Richard Witherspoon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 20:40:17