iOS开发之GPUImage(二)—混合滤镜

作者: 绿豆粥与茶叶蛋 | 来源:发表于2017-04-18 17:31 被阅读1709次

    前言

    本片为GPUImage系列的第二篇,混合滤镜,本篇文章将从两种方式讲解GPUImage混合滤镜的使用。
    本文系列第一篇:初见篇已经完结,感兴趣可以看看:
    iOS开发之GPUImage(一)—初探(给相机加滤镜)

    正文

    GPUImage混合滤镜顾名思义即多种滤镜效果组合使用。就像我们为镜头加一个单独的光亮效果或者怀旧效果,如果想要同时为镜头添加上述两种或者多种滤镜,我们就要用到组合滤镜了。
    GPUImage所提供的混合滤镜有两种方式:

    • GPUImageFilterGroup
    • GPUImageFilterPipeline
    使用GPUImageFilterGroup混合滤镜的步骤如下:

    1)初始化要加载滤镜的GPUImagePicture对象initWithImage: smoothlyScaleOutput:
    2)初始化多个要被使用的单独的GPUImageFilter滤镜
    3)初始化GPUImageFilterGroup对象
    4)将FilterGroup加在之前初始化过的GPUImagePicture上
    5)将多个滤镜加在FilterGroup中(此处切记一定要设置好设置FilterGroup的初始滤镜和末尾滤镜)
    6)之前初始化过的GPUImagePicture处理图片 processImage
    7)拿到处理后的UIImage对象图片imageFromCurrentFramebuffer

    废话少说上代码:

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //加载一个UIImage对象
        UIImage *image = [UIImage imageNamed:@"image.jpg"];
        
        //初始化GPUImagePicture
        _picture = [[GPUImagePicture alloc] initWithImage:image smoothlyScaleOutput:YES];
        
        //反色滤镜
        GPUImageColorInvertFilter *invertFilter = [[GPUImageColorInvertFilter alloc] init];
        
        //伽马线滤镜
        GPUImageGammaFilter *gammaFilter = [[GPUImageGammaFilter alloc]init];
        gammaFilter.gamma = 0.2;
        
        //曝光度滤镜
        GPUImageExposureFilter *exposureFilter = [[GPUImageExposureFilter alloc]init];
        exposureFilter.exposure = -1.0;
        
        //怀旧
        GPUImageSepiaFilter *sepiaFilter = [[GPUImageSepiaFilter alloc] init];
        
        /*
         *FilterGroup的方式混合滤镜
         */
        //初始化GPUImageFilterGroup
        self.myFilterGroup = [[GPUImageFilterGroup alloc] init];
        //将滤镜组加在GPUImagePicture上
        [_picture addTarget:self.myFilterGroup];
        //将滤镜加在FilterGroup中
        [self addGPUImageFilter:invertFilter];
        [self addGPUImageFilter:gammaFilter];
        [self addGPUImageFilter:exposureFilter];
        [self addGPUImageFilter:sepiaFilter];
        //处理图片
        [_picture processImage];
        [self.myFilterGroup useNextFrameForImageCapture];
        //拿到处理后的图片
        UIImage *dealedImage = [self.myFilterGroup imageFromCurrentFramebuffer];
        self.myImageView.image = dealedImage;
    }
    
    #pragma mark 将滤镜加在FilterGroup中并且设置初始滤镜和末尾滤镜
    - (void)addGPUImageFilter:(GPUImageFilter *)filter{
        
        [self.myFilterGroup addFilter:filter];
        
        GPUImageOutput<GPUImageInput> *newTerminalFilter = filter;
        
        NSInteger count = self.myFilterGroup.filterCount;
        
        if (count == 1)
        {
            //设置初始滤镜
            self.myFilterGroup.initialFilters = @[newTerminalFilter];
            //设置末尾滤镜
            self.myFilterGroup.terminalFilter = newTerminalFilter;
            
        } else
        {
            GPUImageOutput<GPUImageInput> *terminalFilter    = self.myFilterGroup.terminalFilter;
            NSArray *initialFilters                          = self.myFilterGroup.initialFilters;
            
            [terminalFilter addTarget:newTerminalFilter];
            
            //设置初始滤镜
            self.myFilterGroup.initialFilters = @[initialFilters[0]];
            //设置末尾滤镜
            self.myFilterGroup.terminalFilter = newTerminalFilter;
        }
    }
    
    
    使用GPUImageFilterPipeline混合滤镜的步骤如下:

    1)初始化要加载滤镜的GPUImagePicture对象initWithImage: smoothlyScaleOutput:
    2)初始化GPUImageView并加在自己的UIImageView对象上
    3)初始化多个要被使用的单独的GPUImageFilter滤镜
    4)把多个单独的滤镜对象放到数组中
    5)初始化创建GPUImageFilterPipeline对象initWithOrderedFilters: input: output:

    参数1:滤镜数组
    参数2:GPUImagePicture对象
    参数3:GPUImageOutput对象如:GPUImageView
    

    6)之前初始化过的GPUImagePicture处理图片 processImage
    7)拿到处理后的UIImage对象图片currentFilteredFrame

    废话少说上代码:

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //加载一个UIImage对象
        UIImage *image = [UIImage imageNamed:@"image.jpg"];
        
        //初始化GPUImagePicture
        _picture = [[GPUImagePicture alloc] initWithImage:image smoothlyScaleOutput:YES];
        
        //反色滤镜
        GPUImageColorInvertFilter *invertFilter = [[GPUImageColorInvertFilter alloc] init];
        
        //伽马线滤镜
        GPUImageGammaFilter *gammaFilter = [[GPUImageGammaFilter alloc]init];
        gammaFilter.gamma = 0.2;
        
        //曝光度滤镜
        GPUImageExposureFilter *exposureFilter = [[GPUImageExposureFilter alloc]init];
        exposureFilter.exposure = -1.0;
        
        //怀旧
        GPUImageSepiaFilter *sepiaFilter = [[GPUImageSepiaFilter alloc] init];
    
        /*
         *GPUImageFilterPipeline的方式混合滤镜
         */
        //初始化myGpuImageView
        _myGpuImageView = [[GPUImageView alloc] initWithFrame:self.myImageView.bounds];
        [self.myImageView addSubview:self.myGpuImageView];
        
        //把多个滤镜对象放到数组中
        NSMutableArray *filterArr = [NSMutableArray array];
        [filterArr addObject:invertFilter];
        [filterArr addObject:gammaFilter];
        [filterArr addObject:exposureFilter];
        [filterArr addObject:sepiaFilter];
        
        //创建GPUImageFilterPipeline对象
        GPUImageFilterPipeline *filterPipline = [[GPUImageFilterPipeline alloc] initWithOrderedFilters:filterArr input:_picture output:self.myGpuImageView];
        
        //处理图片
        [_picture processImage];
        [sepiaFilter useNextFrameForImageCapture];
        
        //拿到处理后的图片
        UIImage *dealedImage = [filterPipline currentFilteredFrame];
    

    效果图如下:


    混合滤镜.png

    源码已上传至fenglinyunshi-git,欢迎下载,并提出宝贵意见。

    结语

    本篇主要讲解了GPUImage框架混合滤镜的两种用法,同样的做法同样可以运用到给相机加滤镜的应用场景中。

    未完待续...

    博观而约取,厚积而薄发。

    相关文章

      网友评论

      • Corbin___:这两种方式是没有区别的吗,我一开始用的是filter渲染完一张图片,再继续用另一个filter渲染图片,达到多个滤镜组合的效果,但是这样渲染的时候内存峰值很高
        十年够不够:@陈泽槟_Corbin 好的。谢谢,我试试。
        Corbin___:@十年够不够 用group会好点吧,不太清楚,后来我改成group了,但是内存没有降
        十年够不够:请问下,使用这个组合滤镜可以减小内存峰值嘛?
      • 38841d8809d0:大神 虑镜组添加一个 twoinput 处理完图后 然后手动再次给虑镜组添加一个 twoinput 类型的虑镜 处理图像没有任何变化 大神这是因为什么
      • 38841d8809d0:大神 给图片做完效果后 再次手动添加一个新的虑镜 然后怎么去回去新处理的图片
      • EDWARDCHENG:你好,看了你的两篇文章很有收货,有个疑问,文章里将的是针对图片做混合滤镜,我尝试针对视频做混合滤镜并录制下来,但失败了,请问楼主有做过吗?能否提供下思路?
        健健锅:添加滤镜 ,那么移除滤镜怎么搞
        冰land:@猿不是员 请问视频的混合滤镜是怎么个思路?能说一下么?
        EDWARDCHENG:搞定了
      • PPAbner:你好,看下http://www.jianshu.com/p/157ff186b8df,感兴趣不,目前已联系4人,他们说的都是500以内,能接受。看看。感兴趣可以参与进来!【如果打扰了,很抱歉】
        PPAbner:@绿豆粥与茶叶蛋 嗯嗯!如果你工作稳定,个人觉得还是再学习学习,毕竟公司的项目不可能用到所有技术方面,而你学的多了,以后跳槽或者开发,更加满意!

      本文标题:iOS开发之GPUImage(二)—混合滤镜

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