iOS Swift中如何移除图像指定区域的模糊效果
实现模糊图像局部清晰的解决方案
核心思路
不要直接修改背景模糊图,而是通过**图层遮罩(CAShapeLayer)**实现:
- 底层是显示模糊效果的
backgroundImage(UIImageView) - 上层叠加一个显示原图的
clearImageView(UIImageView) - 给
clearImageView添加遮罩,遮罩的形状与用户创建的子视图(方形/圆形/矩形)完全匹配,仅遮罩区域显示清晰原图,其余区域透出下方的模糊图
步骤1:初始化视图层级
在ViewController中添加属性并初始化清晰图视图:
var clearImageView: UIImageView! var currentMaskLayer: CAShapeLayer? override func viewDidLoad() { super.viewDidLoad() // 初始化清晰图视图,与backgroundImage同尺寸、同显示模式 clearImageView = UIImageView(image: mainImage) clearImageView.frame = backgroundImage.bounds clearImageView.contentMode = backgroundImage.contentMode backgroundImage.addSubview(clearImageView) clearImageView.isHidden = true // 默认隐藏,有形状视图时再显示 }
步骤2:修改形状按钮点击逻辑
以方形按钮为例,调整视图层级并生成遮罩:
@IBAction func squareButtonTapped(_ sender: Any) { squareView.removeFromSuperview() // 计算正确的初始frame(以背景图中心为原点,调整到视图左上角) let width = CGFloat(backgroundImage.frame.size.width * 10 / 100) let height = CGFloat(backgroundImage.frame.size.height * 20 / 100) let originX = backgroundImage.bounds.midX - width/2 let originY = backgroundImage.bounds.midY - height/2 squareView.frame = CGRect(x: originX, y: originY, width: width, height: height) // 将形状视图添加到清晰图视图上 clearImageView.addSubview(squareView) clearImageView.isHidden = false // 更新遮罩 updateClearMask() }
步骤3:实现遮罩更新方法
创建通用方法,根据当前显示的形状视图生成对应遮罩路径:
func updateClearMask() { let maskLayer = CAShapeLayer() var path: UIBezierPath // 根据当前激活的形状视图生成路径 if squareView.superview != nil { path = UIBezierPath(rect: squareView.frame) } else if circleView.superview != nil { path = UIBezierPath(ovalIn: circleView.frame) } else if rectangleView.superview != nil { path = UIBezierPath(rect: rectangleView.frame) } else { // 无形状视图时隐藏清晰层 clearImageView.isHidden = true return } maskLayer.path = path.cgPath clearImageView.layer.mask = maskLayer currentMaskLayer = maskLayer }
步骤4:修改大小滑块逻辑
调整形状大小时同步更新遮罩:
@IBAction func blurTypeSliderSlides(_ sender: UISlider) { let scale = CGFloat(sender.value / 10) squareView.transform = CGAffineTransform(scaleX: scale, y: scale) // 实时更新遮罩 updateClearMask() }
补充说明
- 圆形/矩形按钮的逻辑与方形按钮一致,仅生成路径时替换为
UIBezierPath(ovalIn:)或对应矩形路径 - 若需支持多个形状同时显示,可将多个路径通过
path.append(_:)合并后设置给遮罩层 - 原模糊滑块的代码无需修改,仅负责更新底层模糊图即可
内容的提问来源于stack exchange,提问作者Asim Iftikhar Abbasi
相关产品推荐
相关产品推荐

