如何实现模糊(毛玻璃)效果

模糊效果,也叫作毛玻璃效果,是设计上挺常用的,尤其是在 iOS 7 之后。

静态的模糊效果自不用说了,直接在 Photoshop 里做好图片就行了。那动态的实时的模糊效果又是怎么做出来的呢?今天我们就来总结一下在 iOS 上的实现动态模糊(毛玻璃)效果的几种方法。

一、对 UIView 进行模糊

iOS 8 增加了 UIVisualEffectView,让我们可以很方便的做出模糊(毛玻璃)效果。

有两点需要注意的:

1、UIVisualEffectView 是个 view,不是方法

刚开始接触的时候,想当然的就以为,有个叫 UIVisualEffect 的方法,例如 UIVisualEffect(myView),就把 myView 给模糊了。这样理解是不对的。UIVisualEffectView 是一个 view,他不是一个方法。你得把UIVisualEffectView 盖在需要某个 view 的上面,他才会帮你把他罩着的小弟都给模糊掉。

如果你熟悉 Photoshop 的话,可以这么理解:程序员说的 View(视图),就是设计师说的 Layer(图层)。UIVisualEffectView 就是个 Adjustment Layer(调节图层),不是 Layer Style(图层样式)。你要对某个 view 进行模糊,就在他上面放一个 UIVisualEffectView 就行了。

2、UIBlurEffect vs UIVibrancyEffect

UIVisualEffectView 包含两种特效,一种叫 UIBlurEffect,一种叫 UIVibrancyEffect。他们都是用来模糊的,区别在于 UIBlurEffect 不会对自身这层进行模糊,UIVibrancyEffect 除了模糊,还会透出一点下面内容的颜色,显得更加艳丽。(见下图)

如何实现模糊(毛玻璃)效果_第1张图片
UIBlurEffect vs UIVibrancyEffect

3、Object-C 的写法

    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    UIVisualEffectView *blurView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    blurView.frame = myView.bounds;
    [myView addSubview:blurView];

UIBlurEffect有三个参数:

  • UIBlurEffectStyleExtraLight 特别亮
  • UIBlurEffectStyleLight 有点亮
  • UIBlurEffectStyleDark 有点黑

4、Swift 的写法

    let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Light)
    let blurView = UIVisualEffectView(effect: blurEffect)
    blurView.frame = myView.bounds
    myView.addSubview(blurView)

UIBlurEffect有三个参数:

  • ExtraLight 特别亮
  • Light 有点亮
  • Dark 有点黑

5、调节模糊半径?

Photoshop 里常用的 Gaussian Blur(高斯模糊,别一不小心写成「搞死模糊」了)有个叫 Radius 的参数,是用来调节模糊半径的,数值越大就越模糊,数值越小就越清晰,UIVisualEffectView 能不能调节模糊半径呢?答案是:没门儿!

网上搜到有人给的方法,就是调节 UIVisualEffectView 的透明度(alpha),透明度低了,模糊效果就没那么明显啦,是不是很机智啊?我去!这馊主意。相信我,这不是设计师能接受的效果。

二、对 UIImage 进行模糊

如果实在想调节模糊半径怎么办?如果要兼容 iOS7,用不了 UIVisualEffectView 怎么办?办法肯定是有的,就是用 CIFilter 滤镜对 UIImage 进行模糊。

用 UIVisualEffectView 和 CIFilter 有什么不同呢?以Photoshop举例,UIVisualEffectView 就好比 Adjustment Layer(调节图层),是对图层进行操作。CIFilter 就像 Gaussian Blur(高斯模糊),是对图片直接进行处理。

Object-C 的写法

-(UIImage *)convertToBlurImage:(UIImage *)image{
    CIFilter *gaussianBlurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
    [gaussianBlurFilter setDefaults];
    CIImage *inputImage = [CIImage imageWithCGImage:[image CGImage]];
    [gaussianBlurFilter setValue:inputImage forKey:kCIInputImageKey];
    [gaussianBlurFilter setValue:@5 forKey:kCIInputRadiusKey];
    CIImage *outputImage = [gaussianBlurFilter outputImage];
    CIContext *context   = [CIContext contextWithOptions:nil];
    CGImageRef cgimg     = [context createCGImage:outputImage fromRect:[inputImage extent]];  // note, use input image extent if you want it the same size, the output image extent is larger
    UIImage *convertedImage = [UIImage imageWithCGImage:cgimg];
    return convertedImage;
}

其中 [gaussianBlurFilter setValue:@5 forKey:kCIInputRadiusKey]; 就是用来设置模糊半径的。

p.s. Swift的代码没有亲测,就不贴出来了。

三、其他第三方库

除了自己苦哈哈的写代码,也可以用第三方库。GitHub 上有丰富的资源,举个例子:

JTSImageViewController 是个开源的Object-C项目,这个项目不是专门做模糊的,人家的追求是做 iOS 里的 Light Box,也就是当用户点击某个图片,这个图片就放大,原来的页面就变黑变模糊作为背景。

其中有一个方法,一看就是居家旅行做模糊效果的必备良药啊:

- (UIImage *)JTS_applyBlurWithRadius:(CGFloat)blurRadius
                           tintColor:(UIColor *)tintColor
               saturationDeltaFactor:(CGFloat)saturationDeltaFactor
                           maskImage:(UIImage *)maskImage;

你可能感兴趣的:(如何实现模糊(毛玻璃)效果)