模糊效果,也叫作毛玻璃效果,是设计上挺常用的,尤其是在 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 除了模糊,还会透出一点下面内容的颜色,显得更加艳丽。(见下图)
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;