iOS几种高斯模糊效果的实现与比较

iOS的模糊效果实现方法有好几种,基本分为两种方式,一种是将图片进行模糊,一种是将模糊的控件放在UI界面上,使控件覆盖的区域达到模糊的效果。每种方式我各选了2种方法,下面介绍一下它们的实现方式以及对比一下它们的优缺点。


屏幕快照 2016-07-29 上午10.10.32.png
coreImage

该方法实现的模糊效果较好,模糊程度的可调范围很大,可以根据实际的需求随意调试。缺点就是耗时,我在模拟器上跑需要1-2秒的时间,所有该方法需要放在子线程中执行。

dispatch_async(dispatch_get_global_queue(0, 0), ^{
        CIContext *context = [CIContext contextWithOptions:nil];
        CIImage *ciImage = [CIImage imageWithCGImage:image.CGImage];
        CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
        [filter setValue:ciImage forKey:kCIInputImageKey];
        //设置模糊程度
        [filter setValue:@30.0f forKey: @"inputRadius"];
        CIImage *result = [filter valueForKey:kCIOutputImageKey];
        CGRect frame = [ciImage extent];
        NSLog(@"%f,%f,%f,%f",frame.origin.x,frame.origin.y,frame.size.width,frame.size.height);
        CGImageRef outImage = [context createCGImage: result fromRect:ciImage.extent];
        UIImage * blurImage = [UIImage imageWithCGImage:outImage];
        dispatch_async(dispatch_get_main_queue(), ^{
            coreImgv.image = blurImage;
        });
    });
vImage

该方法效率高,但是模糊程度最大只能达到上图展示的程度,而且我在使用它对网络加载的图片进行模糊时,整个图片会变红。

//使用前需要导入头文件
#import <Accelerate/Accelerate.h>
+ (UIImage *)boxblurImage:(UIImage *)image withBlurNumber:(CGFloat)blur {
    if (blur < 0.f || blur > 1.f) {
        blur = 0.5f;
    }
    int boxSize = (int)(blur * 40);
    boxSize = boxSize - (boxSize % 2) + 1;
    
    CGImageRef img = image.CGImage;
    
    vImage_Buffer inBuffer, outBuffer;
    vImage_Error error;
    
    void *pixelBuffer;
    //从CGImage中获取数据
    CGDataProviderRef inProvider = CGImageGetDataProvider(img);
    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
    //设置从CGImage获取对象的属性
    inBuffer.width = CGImageGetWidth(img);
    inBuffer.height = CGImageGetHeight(img);
    inBuffer.rowBytes = CGImageGetBytesPerRow(img);
    
    inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);
    
    pixelBuffer = malloc(CGImageGetBytesPerRow(img) *
                         CGImageGetHeight(img));
    
    if(pixelBuffer == NULL)
        NSLog(@"No pixelbuffer");
    
    outBuffer.data = pixelBuffer;
    outBuffer.width = CGImageGetWidth(img);
    outBuffer.height = CGImageGetHeight(img);
    outBuffer.rowBytes = CGImageGetBytesPerRow(img);
    
    error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
    
    if (error) {
        NSLog(@"error from convolution %ld", error);
    }
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(
                                             outBuffer.data,
                                             outBuffer.width,
                                             outBuffer.height,
                                             8,
                                             outBuffer.rowBytes,
                                             colorSpace,
                                             kCGImageAlphaNoneSkipLast);
    CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
    UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
    
    //clean up
    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);
    
    free(pixelBuffer);
    CFRelease(inBitmapData);
    
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(imageRef);
    
    return returnImage;
}

下面两种方法实现起来都很简单,但是只有几种系统提供的样式可选。
BlurEffect是在iOS8之后才出现的,它和toolbar实现的效果基本一样,比toolbar多了一种颜色更深的样式,如上面大图所示。

BlurEffect
UIImageView *blurImgv = [[UIImageView alloc]initWithFrame:CGRectMake(50, 500, 150, 150)];
blurImgv.image = image;
[self.view addSubview:blurImgv];
UIBlurEffect *beffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *view = [[UIVisualEffectView alloc]initWithEffect:beffect];
view.frame = blurImgv.frame;
[self.view addSubview:view];
toolbar
UIImageView *toolImgv = [[UIImageView alloc]initWithFrame:CGRectMake(210, 500, 150, 150)];
toolImgv.image = image;
[self.view addSubview:toolImgv];
UIToolbar *toolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(210, 500, 150, 150)];
toolBar.barStyle = UIBarStyleDefault;
[self.view addSubview:toolBar];

上面介绍了四种实现模糊效果的方法,同时也进行了简单的比较。具体的使用还是要根据项目的需求选择最合适的方法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,420评论 25 708
  • 内容抽屉菜单ListViewWebViewSwitchButton按钮点赞按钮进度条TabLayout图标下拉刷新...
    皇小弟阅读 46,894评论 22 665
  • 当还可以嘘寒问暖时,常回家看看。 ——井溢 文/井溢 漆黑的夜晚,我在人去楼空的...
    井溢阅读 214评论 2 3
  • 今天看完了这一部几个月以前播出的电视剧,自己还是有些许感慨的,就把它写一点下来吧。 首先这部剧从专业的角度来说其...
    南方少年w阅读 1,276评论 0 0
  • 看完了《水浒传》这本书觉得鲁智深是个好汉,并且不是一般的好汉,可能有人觉得鲁智深不仅不是好汉,还是一个坏蛋,但我不...
    米饭说阅读 1,331评论 1 1