ios – 如何制作精确的模糊效果

《ios – 如何制作精确的模糊效果》

我想Blur实际上像第一个Image.

《ios – 如何制作精确的模糊效果》

我做了一些代码并使它像第二个图像.

我的模糊代码就像

    let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
    blurEffectView = UIVisualEffectView(effect: blurEffect)
    blurEffectView.layer.opacity = 0.8
    blurEffectView.alpha = 0.6
    blurEffectView.frame = CGRectMake(0, 42, UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height - 42)
    sourceView.addSubview(blurEffectView)

Sourceview是我的背景视图.我想让它变得模糊.有什么建议吗?

最佳答案 alpha和layer.opacity更正不是必需的,您也可以使用扩展名进行更正:

   extension UIImageView{
       func makeBlurImage(imageView:UIImageView?)
       {
          let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
          let blurEffectView = UIVisualEffectView(effect: blurEffect)
          blurEffectView.frame = imageView!.bounds
          blurEffectView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight] // to support device rotation
          imageView?.addSubview(blurEffectView)
       }
    }

用法:

  let imageView = UIImageView(frame: CGRectMake(0, 100, 300, 400))
  let image:UIImage = UIImage(named: "photo.png")!
  imageView.image =  image
  //Apply blur effect
  imageView.makeBlurImage(imageView)
  self.view.addSubview(imageView)

但是如果你想将模糊效果应用到UIView,你可以使用这个代码:

protocol Blurable
{
    var layer: CALayer { get }
    var subviews: [UIView] { get }
    var frame: CGRect { get }
    var superview: UIView? { get }

    func addSubview(view: UIView)
    func removeFromSuperview()

    func blur(blurRadius blurRadius: CGFloat)
    func unBlur()

    var isBlurred: Bool { get }
}

extension Blurable
{
    func blur(blurRadius blurRadius: CGFloat)
    {
        if self.superview == nil
        {
            return
        }

        UIGraphicsBeginImageContextWithOptions(CGSize(width: frame.width, height: frame.height), false, 1)

        layer.renderInContext(UIGraphicsGetCurrentContext()!)

        let image = UIGraphicsGetImageFromCurrentImageContext()

        UIGraphicsEndImageContext();

        guard let blur = CIFilter(name: "CIGaussianBlur"),
            this = self as? UIView else
        {
            return
        }

        blur.setValue(CIImage(image: image), forKey: kCIInputImageKey)
        blur.setValue(blurRadius, forKey: kCIInputRadiusKey)

        let ciContext  = CIContext(options: nil)

        let result = blur.valueForKey(kCIOutputImageKey) as! CIImage!

        let boundingRect = CGRect(x:0,
            y: 0,
            width: frame.width,
            height: frame.height)

        let cgImage = ciContext.createCGImage(result, fromRect: boundingRect)

        let filteredImage = UIImage(CGImage: cgImage)

        let blurOverlay = BlurOverlay()
        blurOverlay.frame = boundingRect

        blurOverlay.image = filteredImage
        blurOverlay.contentMode = UIViewContentMode.Left

        if let superview = superview as? UIStackView,
            index = (superview as UIStackView).arrangedSubviews.indexOf(this)
        {
            removeFromSuperview()
            superview.insertArrangedSubview(blurOverlay, atIndex: index)
        }
        else
        {
            blurOverlay.frame.origin = frame.origin

            UIView.transitionFromView(this,
                toView: blurOverlay,
                duration: 0.2,
                options: UIViewAnimationOptions.CurveEaseIn,
                completion: nil)
        }

        objc_setAssociatedObject(this,
            &BlurableKey.blurable,
            blurOverlay,
            objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
    }

    func unBlur()
    {
        guard let this = self as? UIView,
            blurOverlay = objc_getAssociatedObject(self as? UIView, &BlurableKey.blurable) as? BlurOverlay else
        {
            return
        }

        if let superview = blurOverlay.superview as? UIStackView,
            index = (blurOverlay.superview as! UIStackView).arrangedSubviews.indexOf(blurOverlay)
        {
            blurOverlay.removeFromSuperview()
            superview.insertArrangedSubview(this, atIndex: index)
        }
        else
        {
            this.frame.origin = blurOverlay.frame.origin

            UIView.transitionFromView(blurOverlay,
                toView: this,
                duration: 0.2,
                options: UIViewAnimationOptions.CurveEaseIn,
                completion: nil)
        }

        objc_setAssociatedObject(this,
            &BlurableKey.blurable,
            nil,
            objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
    }

    var isBlurred: Bool
    {
        return objc_getAssociatedObject(self as? UIView, &BlurableKey.blurable) is BlurOverlay
    }
}

extension UIView: Blurable
{
}

class BlurOverlay: UIImageView
{
}

struct BlurableKey
{
    static var blurable = "blurable"
}

Swift 4.x

extension UIView {
struct BlurableKey {
    static var blurable = "blurable"
}

func blur(radius: CGFloat) {
    guard let superview = superview else { return }

    UIGraphicsBeginImageContextWithOptions(CGSize(width: frame.width, height: frame.height), false, 1)

    layer.render(in: UIGraphicsGetCurrentContext()!)

    guard let image = UIGraphicsGetImageFromCurrentImageContext() else { return }

    UIGraphicsEndImageContext()

    guard let blur = CIFilter(name: "CIGaussianBlur") else { return }

    blur.setValue(CIImage(image: image), forKey: kCIInputImageKey)
    blur.setValue(radius, forKey: kCIInputRadiusKey)

    let ciContext  = CIContext(options: nil)
    guard let result = blur.value(forKey: kCIOutputImageKey) as? CIImage else { return }
    let boundingRect = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
    guard let cgImage = ciContext.createCGImage(result, from: boundingRect) else { return }
    let filteredImage = UIImage(cgImage: cgImage)

    let blurOverlay = UIImageView()
    blurOverlay.frame = boundingRect

    blurOverlay.image = filteredImage
    blurOverlay.contentMode = UIViewContentMode.left

    if let stackView = superview as? UIStackView, let index = stackView.arrangedSubviews.index(of: self) {
        removeFromSuperview()
        stackView.insertArrangedSubview(blurOverlay, at: index)

    } else {
        blurOverlay.frame.origin = frame.origin

        UIView.transition(from: self,
                          to: blurOverlay,
                          duration: 0.2,
                          options: UIViewAnimationOptions.curveEaseIn,
                          completion: nil)
    }

    objc_setAssociatedObject(self,
                             &BlurableKey.blurable,
                             blurOverlay,
                             objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}

func unBlur() {
    guard let blurOverlay = objc_getAssociatedObject(self, &BlurableKey.blurable) as? UIImageView else { return }

    if let stackView = blurOverlay.superview as? UIStackView, let index = stackView.arrangedSubviews.index(of: blurOverlay) {
        blurOverlay.removeFromSuperview()
        stackView.insertArrangedSubview(self, at: index)

    } else {
        frame.origin = blurOverlay.frame.origin

        UIView.transition(from: blurOverlay,
                          to: self,
                          duration: 0.2,
                          options: UIViewAnimationOptions.curveEaseIn,
                          completion: nil)
    }

    objc_setAssociatedObject(self,
                             &BlurableKey.blurable,
                             nil,
                             objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}

var isBlurred: Bool {
    return objc_getAssociatedObject(self, &BlurableKey.blurable) is UIImageView
}
}

用法是例如:

segmentedControl.unBlur()
segmentedControl.blur(blurRadius: 2)

这是Blurable项目的来源.

您可以在他的GitHub项目here中找到更多细节

点赞