在ios开发过程中,为了界面的美观,我们往往需要对一个图片进行模糊化处理,有一种朦胧美得感觉,就是所谓的毛玻璃效果。在GitHub上不乏实现毛玻璃效果的三方框架,这里就不做过多介绍。现在主要谈谈苹果自己提供的两种实现毛玻璃效果的类,UIToolBar和UIVisuaEffectView。
UIToolBar
UIToolBar在IOS 2.0就已经出现,可以快速实现毛玻璃效果。简单易懂,但是效果单一,系统只提供了两种bayStyle. UIBarStyleDefault和UIBarStyleBlack 。
Snip20160717_9.png Snip20160717_8.png//背景图片
UIImageView *backImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"Snip20160714_17"]];
backImageView.frame = self.view.bounds;
[self.view addSubview:backImageView];
//UIToolBar:加了三层遮盖
UIToolbar *bar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 100,375, 300)];
bar.barStyle = UIBarStyleDefault;
bar.alpha = 0.8;
[self.view addSubview:bar];
UIVisuaEffectView
UIVisuaEffectView是苹果从IOS8.0开始提供的可实现毛玻璃效果(blur)的控件。相比以前的UIToolBar,UIVisuaEffectView的功能更加强大,能实现更加复杂的效果。 利用UIVisuaEffectView实现毛玻璃效果,首先需要对UIVisualEffect,UIBlurEffect、UIVibrancyEffect 和UIVisuaEffectView有一个正确的认识:
-
1.UIVisuaEffectView :继承自UIView,可以看成是专门用于处理毛玻璃效果的视图,只要我们将这个特殊的View添加到其他视图(eg. ImageView )上面,被该UIVisuaEffectView遮盖的部分看起来就有了毛玻璃效果。使用UIVisuaEffectView有一点需要特别注意,不要在UIVisuaEffectView实例化View上面直接添加subViews,应该将需要添加的子视图添加到其contentView上。同时,尽量避免将UIVisualEffectView对象的alpha值设置为小于1.0的值,因为创建半透明的视图会导致系统在离屏渲染时去对UIVisualEffectView对象及所有的相关的子视图做混合操作,比较消耗性能。
-
2.UIBlurEffect:毛玻璃效果。使用该效果,会使得UIVisualEffectView下面的内容出现毛玻璃化,但是添加到contentView的View不会受影响。
-
3.UIVibrancyEffect:生动效果。该效果,能够放大和调整放在UIVisualEffectView对象下面的内容的颜色,也能让添加在contentView中的内容变得更加生动。它可以放在一个配置了UIBlurEffect效果的UIVisualEffectView的上面或者作为其subView。这种效果仅仅对与添加到contentView中的内容有效果。因为这种生动效果依赖于颜色,添加到contentView中的subViews 需要实现tintColorDidChange方法,并及时更新。如果是UIImageView,必须设置其渲染方式为UIImageRenderingModeAlwaysTemplate。
-
4. UIVisualEffect:一个视觉效果抽象类,继承自NSObject,是UIBlurEffect和UIVibrancyEffect的父类。
具体代码和效果:
利用UIVisuaEffectView实现毛玻璃效果,首先需要创建一个UIVisuaEffectView对象,同时给该对象指定一种处理效果(UIBlurEffect/UIVibrancyEffect)。
1). UIBlurEffect
//设置背景图片
UIImageView *backImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"Snip20160714_17"]];
backImageView.frame = self.view.bounds;
[self.view addSubview:backImageView];
//设置UIVisualEffectView
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *visualView = [[UIVisualEffectView alloc]initWithEffect:blurEffect];
visualView.frame = CGRectMake(0, 100,375, 300);
[self.view addSubview:visualView];
//UIBlurEffect的effectWithStyle有三种:UIBlurEffectStyleExtraLight/UIBlurEffectStyleLight/UIBlurEffectStyleDark
Snip20160717_1.png
Snip20160717_3.png
可以看出使用UIBlurEffect 其实是在图片上面添加了三层遮盖。所以,如果图片放在了UIVisualEffectView的上面就没有效果。
2). UIVibrancyEffect
//设置背景图片
UIImageView *backImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"Snip20160714_17"]];
backImageView.frame = self.view.bounds;
[self.view addSubview:backImageView];
//UIVisualEffectView
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVibrancyEffect *vibrancyEffect = [UIVibrancyEffect effectForBlurEffect:blurEffect];
UIVisualEffectView *visualView = [[UIVisualEffectView alloc]initWithEffect:vibrancyEffect];
UIView *redView = [[UIView alloc]init];
redView.backgroundColor = [UIColor redColor];
[visualView.contentView addSubview:redView];
visualView.frame = CGRectMake(0, 100,375, 300);
redView.frame = visualView.bounds;
[self.view addSubview:visualView];
通过改变contentView中subView,可以实现不同更加生动的效果。
Snip20160717_5.png Snip20160717_6.png补充
- 鉴于下面一位热心的朋友提示,自己就抽时间稍微看了一下Core Image相关的东西。Core Image是苹果提供的一个相当强大专门用于处理图片的库。稍微试了一下,不仅能实现毛玻璃效果,还能实现很多其他的效果。但是,在使用过程中发现使用Core Image来实现这些效果,非常占用内存。查看文档:createCGImage:outputImage : fromRect:方法会单独开辟一个临时的缓存区,出现离屏渲染,这可能是一个使得内存增大的重要原因。
render the region 'fromRect' of image 'image' into a temporary buffer using the context, then create and return a new CoreGraphics image with the results.
- 下面简单看下效果吧
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIImageView *iconImageView;
@property (strong, nonatomic) IBOutlet UIImageView *blurImageVIew;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//1.获取CIIamge对象
CIImage * ciIamge = [CIImage imageWithCGImage:_iconImageView.image.CGImage];
// //2.创建滤镜对象
CIFilter *filter = [CIFilter filterWithName:@"CIMotionBlur"
keysAndValues:kCIInputImageKey, ciIamge, nil];
// 获取绘制上下文
CIContext *context = [CIContext contextWithOptions:nil];
// 渲染并输出CIImage
CIImage *outputImage = [filter outputImage];
// 创建CGImage句柄
CGImageRef cgImage = [context createCGImage:outputImage
fromRect:[outputImage extent]];
self.blurImageVIew.image =[UIImage imageWithCGImage:cgImage];
self.blurImageVIew.contentMode = UIViewContentModeScaleAspectFill;
// 释放CGImage句柄
CGImageRelease(cgImage);
// self.blurImageVIew.image = self.iconImageView.image;
}
Snip20160827_4.png
-
未使用Core Image
未使用.png -
使用Core Image
- 其他效果。只需传入不同的滤镜的name,上面选择的是:CIMotionBlur 。具体可以选择的name 可以参考
https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/filter/ci/CIMotionBlur
网友评论