剧情介绍
在iOS开发中,经常会看到毛玻璃效果,也叫模糊效果,比如系统的通知中心,这个很时髦的效果增加了美观性。
通知中心的模糊效果
查看资料发现实现毛玻璃效果有很多种方式,下面总结了其中几种方式。
静态模糊效果
- 对于静态的模糊效果,最直接的方式就是加载做好的模糊图片
动态模糊效果
- 苹果原生控件:
UIVisualEffectView
- 苹果原生API:Core Image 的滤镜效果
- 苹果原生API:vImage
- 使用第三方工具GPUImage
- 使用第三方工具FXBlurView
- ...
一、苹果原生控件:UIVisualEffectView
实现模糊效果
-
UIVisualEffectView
是iOS8的新特性,该控件主要用于为原有的控件增加模糊效果。 - 由于是iOS8的新特性,所以具有一定的局限性。
-
UIVisualEffectView
继承自UIView,没有继承UIControl,所以只能做静态控件使用。 - 控制
UIVisualEffectView
控件模糊效果的属性时effect
只读属性,该属性的类型是UIVisualEffect
,该类型有两个子类:UIBlurEffect
和UIVibrancyEffect
。 -
UIBlurEffect
允许应用程序中动态的创建实时的模糊效果;UIVibrancyEffect
允许在模糊效果上“写字”。 - Blur Style有三种效果:
-
UIBlurEffectStyleLight
:白色的模糊效果。 -
UIBlurEffectStyleExtraLight
:极亮的白色模糊效果。 -
UIBlurEffectStyleDark
:暗色的模糊效果。
-
- 可以通过在Interface Bulider中将
UIVibrancyEffect
控件直接拖入某个控件内添加模糊效果,也可以通过纯代码的形式创建和添加。
// UIBlurEffectStyleLight模式
UIVisualEffectView *lightView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
lightView.frame = CGRectMake(40, 40, 300, 100);
[self.imageView addSubview:lightView];
// UIBlurEffectStyleExtraLight模式
UIVisualEffectView *extraLightView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight]];
extraLightView.frame = CGRectMake(40, 160, 300, 100);
[self.imageView addSubview:extraLightView];
// UIBlurEffectStyleDark
UIVisualEffectView *darkView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
darkView.frame = CGRectMake(40, 280, 300, 100);
[self.imageView addSubview:darkView];
二、Core Image 的滤镜效果实现模糊效果
- 在iOS5.0之后Core Image 的API提供了大量的滤镜(Filter)效果。
- 利用Core Image 实现模糊效果非常简单,只需要10行左右的代码就能搞定。
- 使用Core Image 设置模糊之后,会在周围产生白边。
- 代码中的
CIGaussianBlur
是一个滤镜名称,更多的滤镜可以参考苹果滤镜列表 -
Core Image
实现高斯模糊的原理是:将原来的图片惊醒模糊处理返回渲染后的一整张图片,比较消耗CPU性能。
/**
* 使用Core Image进行模糊
*/
- (UIImage *)blurryImage:(UIImage *)image withblurLevel:(CGFloat)blur{
// 1.创建CIImage
CIImage * ciImage = [[CIImage alloc]initWithImage:image];
// 2.添加滤镜
CIFilter * blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
// 3.将图片输入到滤镜中
[blurFilter setValue:ciImage forKey:kCIInputImageKey];
// 4.设置模糊值(不模糊为0,模糊最大为100)
[blurFilter setValue:[NSNumber numberWithFloat:blur] forKey:@"inputRadius"];
// 5.将处理好的图片输出
CIImage * outCiImage = [blurFilter valueForKey:kCIOutputImageKey];
// 6.生成图片 CIContext(CIImage的操作句柄)nil表示默认有CPU渲染图片(如果让GPU渲染提高效率,则应设置contextWithOptions的字典数据)
CIContext * context = [CIContext contextWithOptions:nil];
// 7.获取CIImage句柄
CGImageRef outCGImage = [context createCGImage:outCiImage fromRect:[outCiImage extent]];
// 8.最终获取到图片
UIImage * blurImage = [UIImage imageWithCGImage:outCGImage];
// 9.释放句柄
CGImageRelease(outCGImage);
return blurImage;
}
Core Image实现高斯模糊
三、使用vImage
实现高斯模糊
-
vImage
属于Accelerate.Framework
,所以在使用是需要导入Accelerate
头文件,导入头文件代码:#import <Accelerate/Accelerate.h>
-
Accelerate
主要用来做数图像处理、字信号处理相关的向量、矩阵运算的库。 - 图像可以认为是由向量后者矩阵数据构成的。
-
Accelerate
提供了搞笑的数学运算API,所以能对图像做各种各样的处理。 -
Accelerate
实现高斯模糊的原理是:将原来的图片惊醒模糊处理返回渲染后的一整张图片,比较消耗CPU。 - 模糊算法使用的函数是:
vImageBoxConvolve_ARGB8888
代码
(记得先导入头文件#import <Accelerate/Accelerate.h>
)
/**
* 使用vImage实现模糊效果
*/
- (UIImage *)blurryImage:(UIImage *)image withblur:(CGFloat)blur{
if (blur < 0.f || blur > 1.0f) blur = 0.5f;
int boxSize = (int)(blur * 100);
boxSize -=(boxSize % 2) + 1;
// 图像处理
CGImageRef img = image.CGImage;
// 输入缓存 输出缓存
vImage_Buffer inBuffer,outBuffer;
vImage_Error error;
// 像素缓存
void * pixelBuffer;
//数据源提供者,Defines an opaque type that supplies Quartz with data.
CGDataProviderRef inProvider = CGImageGetDataProvider(img);
// provider’s data.
CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
//宽,高,字节/行,data
inBuffer.width = CGImageGetWidth(img);
inBuffer.height = CGImageGetHeight(img);
inBuffer.rowBytes = CGImageGetBytesPerRow(img);
inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);
//像数缓存,字节行*图片高
pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
outBuffer.data = pixelBuffer;
outBuffer.width = CGImageGetWidth(img);
outBuffer.height = CGImageGetHeight(img);
outBuffer.rowBytes = CGImageGetBytesPerRow(img);
// 第三个中间的缓存区,抗锯齿的效果
void *pixelBuffer2 = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
vImage_Buffer outBuffer2;
outBuffer2.data = pixelBuffer2;
outBuffer2.width = CGImageGetWidth(img);
outBuffer2.height = CGImageGetHeight(img);
outBuffer2.rowBytes = CGImageGetBytesPerRow(img);
//Convolves a region of interest within an ARGB8888 source image by an implicit M x N kernel that has the effect of a box filter.
error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer2, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
error = vImageBoxConvolve_ARGB8888(&outBuffer2, &inBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
if (error) NSLog(@"error from convolution %ld", error);
// NSLog(@"字节组成部分:%zu",CGImageGetBitsPerComponent(img));
//颜色空间DeviceRGB
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//用图片创建上下文,CGImageGetBitsPerComponent(img),7,8
CGContextRef ctx = CGBitmapContextCreate(
outBuffer.data,
outBuffer.width,
outBuffer.height,
8,
outBuffer.rowBytes,
colorSpace,
CGImageGetBitmapInfo(image.CGImage));
//根据上下文,处理过的图片,重新组件
CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
UIImage * outImage = [UIImage imageWithCGImage:imageRef];
//clean up
CGContextRelease(ctx);
CGColorSpaceRelease(colorSpace);
free(pixelBuffer);
free(pixelBuffer2);
CFRelease(inBitmapData);
//CGColorSpaceRelease(colorSpace); //多余的释放
// 释放句柄
CGImageRelease(imageRef);
return outImage;
}
使用vImage实现高斯模糊
四、使用第三方工具GPUImage实现高斯模糊
-
GPUImage
一个基于GPU图像和视频处理的开源框架,适用面广。 -
GPUImage
同时支持objective-C和Swift。 -
GPUImage
的github地址GPUImage -
GPUImage
可以直接导入本地,也可以使用使用pod导入。这是使用pod比较简单。 - 使用
GPUImage
实现高斯模糊的代码非常简单.
/**
*使用GPUImage实现高斯模糊
*/
- (UIImage *)blurryGPUImage:(UIImage *)image withBlurLevel:(CGFloat)blur{
GPUImageGaussianBlurFilter * blurFilter = [[GPUImageGaussianBlurFilter alloc]init];
blurFilter.blurRadiusInPixels = blur;
UIImage * blurImage = [blurFilter imageByFilteringImage:image];
return blurImage;
}
使用第三方工具GPUImage实现高斯模糊
五、 使用第三方工具FXBlurView实现高斯模糊
-
FXBlurView
是UIView的子类,支持iOS5.0及其以上 -
FXBlurView
的特点是简单和轻快,看源码就知道几行代码就可以搞定。 -
FXBlurView
有两种模式:static
静态模糊,也就是只模糊一次,就算背景图片改变了模糊效果也不会改变;dynamic
动态模糊,也就是会实时的对背景图片进行模糊,是会不断变化的。 -
FXBlurView
同样也可以通过pod导入。 -
FXBlurView
的原理是在图片上添加一个FXBlurView
的对象覆盖原图。
// 设置模糊效果
FXBlurView * blurView = [[FXBlurView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 200)];
blurView.backgroundColor = [UIColor whiteColor];
// 设置模式
blurView.dynamic = YES;
// 设置模糊半径
blurView.blurRadius = 10.0;
使用第三方工具FXBlurView实现高斯模糊
demo后续上传
网友评论