美文网首页iOS开发
iOS 如何实现模糊效果

iOS 如何实现模糊效果

作者: 波波熊洛夫 | 来源:发表于2015-11-18 13:57 被阅读1739次

    写于2013-04-22


    随着App Store的发展,越来越多的应用进入人们的视野,只是纯粹靠着功能强大来吃饭的应用已经跟不上时代。排行榜名列前茅的应用可能功能并不是最强大的,但绝对是最吸引眼球的。或者炫目的效果,或者简洁清新的风格,又或者流畅新颖的操作方式,这些才能让你的应用足够“特别”。

    良好的视觉效果是一款优秀应用所必备的元素,以往人们觉得视觉效果只是美术设计人员的职责,但是随着iOS SDK的发展更新,越来越多简便的图形化API的出现,让程序员自己也能通过简单的几行代码实现美术人员用PS等软件才能实现的效果,毕竟PS也只是Adobe公司开发的一款软件而已。

    在所有视觉效果里,模糊效果可能是最常用的了。模糊效果一般用来描述视觉的层次感,为了突出某个物体而模糊其背景来衬托,或者为了描述物体的动态感等等。本文将通过两个图形框架讲解最常用的一种模糊,高斯模糊

    Core Image

    毋庸置疑,在iOS提到图片处理,第一个想到的就是Core Image框架。Core Image框架在iOS5被引进SDK,可用于处理静态图像和视频,并同时使用CPU和GPU进行处理工作。Core Image使用过滤器(fliter)来处理图片,过滤器是一个包含图片处理效果的对象。处理图片时,只需要将原图传给过滤器,过滤器就会返回处理后的结果了。Core Image处理图片的步骤如下图所示:

    可总结成以下几个步骤:

    1. 首先创建一个图片对象CIImage,然后再创建context对象CIContext
    2. 然后获取所需要的过滤器。
    3. 然后将过滤器绑定到图片对象上。
    4. 最后,从过滤器得到处理结果,即处理后的图片。

    一般来说这就是使用Core Image的基本步骤了。但是需要注意的是,在iOS上并不是文档里所有的过滤器都能使用,在使用过滤器之前,需要先查看其是否支持iOS平台。下面就是使用Core Image实现高斯模糊的代码实例:

    - (UIImage *)blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur {
        CIImage *inputImage = [CIImage imageWithCGImage:image.CGImage];
        CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"
                                      keysAndValues:kCIInputImageKey, inputImage, 
                                      @"inputRadius", @(blur), nil];
        
        CIImage *outputImage = filter.outputImage;
        CIContext *context = [CIContext contextWithOptions:nil]; // save it to self.context
        CGImageRef outImage = [context createCGImage:outputImage fromRect:[outputImage extent]];
        return [UIImage imageWithCGImage:outImage];
    }
    

    如果你以为这样就可以了就错了,如果当你需要使用好几种过滤器混合或者需要实时的生成模糊效果的话,你会发现Core Image的速度开始变慢,有时慢的无法使用。所以在使用Core Image时还需要注意效率问题,官方文档总结了一个页面,主要是以下几点:

    • 不要每次处理的时候都创建一个新的CIContext,这是因为每次创建CIContext几乎等于为每一个图片创建一个新的OpenGL context,这样的开销非常大。所以创建一个,然后保存起来,每次都使用那一个即可,查看上面代码第8行的注释。
    • 合理选择使用CPU还是GPU。一般GPU只有在处理视频时才具有优势,所以一般都使用CPU来处理。当你同时使用Core Animation或者Core Graphics时,都会降低GPU的效率。如果需要显式的使用GPU,初始化CIContext时使用contextWithEAGLContext函数。
    • 尽量减小图片的尺寸,并注意不要超过CPU或GPU能处理的最大尺寸,可查看inputImageMaximumSizeoutputImageMaximumSize属性。

    GPUImage

    GPUImage是一个非常有名的处理图片和视频的开源库。跟Core Image类似,GPUImage也是使用过滤器的方式来处理图片。正如其名,GPUImage几乎都是使用GPU来做处理工作,所以和Core Image相比,GPUImage在视频处理的优势非常大,快了不是一点。即使是图片处理,GPUImage也基本上比Core Image的效率更高。

    使用GPUImage处理图片甚至比Core Image更简单,只需要将过滤器赋给图片对象即可,不用考虑context或者设备等其他问题。GPUImage提供了除高斯模糊外的其他几种不同效果的模糊,虽然Core Image也提供了几种模糊效果,但目前在iOS上能用的就只有高斯模糊,而GPUImage可用的有FastBlur, GaussianBlur, GaussianSelectiveBlurBoxBlur。GPUImage还支持自定义的过滤器,因为是开源框架。

    使用GPUImage实现模糊效果的代码如下:

    - (UIImage *)blurryGPUImage:(UIImage *)image withBlurLevel:(NSInteger)blur {
        GPUImageFastBlurFilter *blurFilter = [[GPUImageFastBlurFilter alloc] init];
        blurFilter.blurSize = blur;
        UIImage *result = [blurFilter imageByFilteringImage:image];
        return result;
    }
    

    Core Image vs GPUImage

    根据Core Image和GPUImage的实际使用效果上看,我得出的结论是,在不考虑效率问题或有特别需求的时候,使用Core Image。因为Core Image是iOS自带框架,不需要配置直接使用,而且从我实验高斯模糊的效果上看,Core Image得到的效果要好于GPUImage,但这并不能说明Core Image的效果比GPUImage要好。

    但如果需要实时模糊或复杂效果实现时,Core Image的效率就远远跟不上了,经常出现顿卡现象。这时使用GPUImage说不定会有惊喜。有人通过实验证明GPUImage的效率几乎全面胜过Core Image,实验的工程见BlurCompare。使用GPUImage也非常简单,具体请查看其Github主页

    相关文章

      网友评论

        本文标题:iOS 如何实现模糊效果

        本文链接:https://www.haomeiwen.com/subject/kxhlhttx.html