美文网首页
GPUImage 学习一(开篇:简单实现滤镜效果)

GPUImage 学习一(开篇:简单实现滤镜效果)

作者: 古子林 | 来源:发表于2017-12-27 10:38 被阅读269次

    近来公司业务转型,想试水微信小程序,苦逼的我被迫搞起了小程序开发。在上架两款小程序,迭代多个版本后,个人感觉小程序的效益并不理想(不是说小程序行情不好,只是公司的产品定位和战略个人不太认可)。与此同时我也突然意识到自己居然都有两个月没有接触iOS开发相关的知识了😱,不由得脊柱发凉,于是决定重回老本行。就从GPUImage这个库开始吧。

    本篇内容:
    1,简单实现一个单滤镜效果
    2,组合滤镜的两种使用方式
    3,所有滤镜头文件注释(这个也是在网上找的,有些解释我也不太理解,先写着,我后续会逐一研究每个效果,并纠正注释)

    实现一个单滤镜效果(亮度)

    先看界面效果:


    亮度
    
    GPUImageBrightnessFilter *brightnessFilter = [[GPUImageBrightnessFilter alloc] init];
    brightnessFilter.brightness = slider.value;
    
    GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:_image];
    [pic addTarget:brightnessFilter];
    [pic processImage];
        
    // 使用 imageFromCurrentFramebuffer 前需要先调用 useNextFrameForImageCapture
    [brightnessFilter useNextFrameForImageCapture];
    _imageView.image = [brightnessFilter imageFromCurrentFramebuffer];
    [pic removeOutputFramebuffer];
    

    注意:

    1,用imageFromCurrentFramebuffer 前一定要先调用useNextFrameForImageCapture,否则获取到的将是一个空对象

    官方解释
    // If you're trying to use these methods, remember that you need to set -useNextFrameForImageCapture before running -processImage or running video and calling any of these methods, or you will get a nil image
    

    2,图片处理完成后要 removeOutputFramebuffer (这里pic是局部变量,方法执行完会自动释放,看不出效果,如果为全局变量就会发现不移除缓存的话,会导致内存一直存在,如果图片比较大很容易导致内存飙升,这个我在网上找的所有资料中都没有说明)

    也可以这样:

    单滤镜也可以用imageByFilteringImage进行处理,这样就只需一行代码就行了(实际上是imageByFilteringImage方法内部帮我们做了其他步骤)

    GPUImageBrightnessFilter *brightnessFilter = [[GPUImageBrightnessFilter alloc] init];
    brightnessFilter.brightness = slider.value;
    _imageView.image = [brightnessFilter imageByFilteringImage:_image];
    
    也可以这样:

    也可以用GPUImageView作为输出源

    GPUImageBrightnessFilter *brightnessFilter = [[GPUImageBrightnessFilter alloc] init];
    brightnessFilter.brightness = slider.value;
    
    [brightnessFilter addTarget:gpuImageView];    // gpuImageView为一个GPUImageView对象
    [pic addTarget:brightnessFilter];
    [pic processImage];
    [pic removeOutputFramebuffer];
    

    组合滤镜的两种使用方式

    先看界面效果:


    组合滤镜

    界面布局:
    下面代码 values 中 min滤镜效果的最小值,max滤镜效果的最大值,default滤镜效果的默认值

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 64, self.view.bounds.size.width, self.view.bounds.size.height / 2.0)];
        _image = [UIImage imageNamed:@"zilin.jpeg"];
        _imageView.image = _image;
        _imageView.contentMode = UIViewContentModeScaleAspectFit;
        [self.view addSubview:_imageView];
        
        CGFloat top = self.view.center.y + 100;
        NSArray *titles = @[@"亮度",@"饱和度",@"对比度",@"锐度"];
        NSArray *values = @[@{@"min":@(-1),@"max":@(1),@"default":@(0)},
                            @{@"min":@(0),@"max":@(2),@"default":@(1)},
                            @{@"min":@(0),@"max":@(4),@"default":@(1)},
                            @{@"min":@(-4),@"max":@(4),@"default":@(0)}
                            ];
        _brightness = 0;
        _saturation = 1;
        _contrast = 1;
        _sharpness = 0;
        for (int i = 0; i < titles.count; i ++) {
            
            UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, top + i * (30 + 30), 80, 30)];
            titleLabel.textAlignment = NSTextAlignmentCenter;
            titleLabel.text = titles[i];
            [self.view addSubview:titleLabel];
            
            UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(100, top + i * (30 + 30), self.view.bounds.size.width - 100 - 10, 30)];
            [slider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
            slider.tag = i + 1;
            NSDictionary *dic = values[i];
            slider.minimumValue = [dic[@"min"] floatValue];
            slider.maximumValue = [dic[@"max"] floatValue];
            slider.value = [dic[@"default"] floatValue];
            [self.view addSubview:slider];
            
        }
    }
    



    事件处理

    方法一:滤镜叠加(以链式进行串联)

    - (void)sliderValueChanged:(UISlider *)sender{
        CGFloat value = sender.value;
        switch (sender.tag) {
            case 1: // 亮度
                _brightness = value;
                break;
            case 2: // 饱和度
                _saturation = value;
                break;
            case 3: // 对比度
                _contrast = value;
                break;
            case 4: // 锐度
                _sharpness = value;
                break;
        }
        
        GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:_image];
        
        GPUImageBrightnessFilter *brightnessFilter = [[GPUImageBrightnessFilter alloc] init];
        brightnessFilter.brightness = _brightness;
        GPUImageSaturationFilter *saturationFilter = [[GPUImageSaturationFilter alloc] init];
        saturationFilter.saturation = _saturation;
        GPUImageContrastFilter *contrastFilter = [[GPUImageContrastFilter alloc] init];
        contrastFilter.contrast = _contrast;
        GPUImageSharpenFilter *sharpenFilter = [[GPUImageSharpenFilter alloc] init];
        sharpenFilter.sharpness = _sharpness;
        
        //  滤镜的叠加(链式串联,注意顺序)
        [brightnessFilter addTarget:saturationFilter];
        [saturationFilter addTarget:contrastFilter];
        [contrastFilter addTarget:sharpenFilter];
    
        [pic addTarget:brightnessFilter];
        [pic processImage];
    
        // 使用 imageFromCurrentFramebuffer 前需要先调用 useNextFrameForImageCapture
        [sharpenFilter useNextFrameForImageCapture];
        _imageView.image = [sharpenFilter imageFromCurrentFramebuffer];
        [pic removeOutputFramebuffer];
        
    }
    

    方法二:GPUImageFilterGroup

    - (void)sliderValueChanged:(UISlider *)sender{
        CGFloat value = sender.value;
        switch (sender.tag) {
            case 1: // 亮度
                _brightness = value;
                break;
            case 2: // 饱和度
                _saturation = value;
                break;
            case 3: // 对比度
                _contrast = value;
                break;
            case 4: // 锐度
                _sharpness = value;
                break;
        }
        
        
        GPUImagePicture *pic = [[GPUImagePicture alloc] initWithImage:_image];
        
        GPUImageBrightnessFilter *brightnessFilter = [[GPUImageBrightnessFilter alloc] init];
        brightnessFilter.brightness = _brightness;
        GPUImageSaturationFilter *saturationFilter = [[GPUImageSaturationFilter alloc] init];
        saturationFilter.saturation = _saturation;
        GPUImageContrastFilter *contrastFilter = [[GPUImageContrastFilter alloc] init];
        contrastFilter.contrast = _contrast;
        GPUImageSharpenFilter *sharpenFilter = [[GPUImageSharpenFilter alloc] init];
        sharpenFilter.sharpness = _sharpness;
        
        [brightnessFilter addTarget:saturationFilter];
        [saturationFilter addTarget:contrastFilter];
        [contrastFilter addTarget:sharpenFilter];
    
        // GPUImageFilterGroup
        GPUImageFilterGroup *filterGroup = [[GPUImageFilterGroup alloc] init];
        // 设置Group的起点和终点滤镜效果
        filterGroup.initialFilters = @[brightnessFilter];
        filterGroup.terminalFilter = sharpenFilter;
    
        [pic addTarget:filterGroup];
        [pic processImage];
    
        [filterGroup useNextFrameForImageCapture];
        _imageView.image = [filterGroup imageFromCurrentFramebuffer];
        [pic removeOutputFramebuffer];
    }
    

    所有滤镜头文件注释

    (这个也是在网上找的,有些解释我也不太理解,先写着,我后续会逐一研究每个效果,并纠正注释)

    // Filters
    #import "GPUImageFilter.h"                          // 所有滤镜的基类
    #import "GPUImageTwoInputFilter.h"                  // 双输入滤镜
    #import "GPUImagePixellateFilter.h"                 // 像素化
    #import "GPUImagePixellatePositionFilter.h"         // 像素点
    #import "GPUImageSepiaFilter.h"                     // 褐色(怀旧)
    #import "GPUImageColorInvertFilter.h"               // 反色
    #import "GPUImageSaturationFilter.h"                // 饱和度
    #import "GPUImageContrastFilter.h"                  // 对比度
    #import "GPUImageExposureFilter.h"                  // 曝光
    #import "GPUImageBrightnessFilter.h"                // 亮度
    #import "GPUImageLevelsFilter.h"                    // 色阶
    #import "GPUImageSharpenFilter.h"                   // 锐度
    #import "GPUImageGammaFilter.h"                     // 伽马射线
    #import "GPUImageSobelEdgeDetectionFilter.h"        // Sobel边缘检测算法(白边,黑内容,有点漫画的反色效果)
    #import "GPUImageSketchFilter.h"                    // 素描
    #import "GPUImageToonFilter.h"                      // 卡通效果(黑色粗线描边)
    #import "GPUImageSmoothToonFilter.h"                // 相比Toon更细腻更平滑
    #import "GPUImageMultiplyBlendFilter.h"             // 多层混合效果,通常用于创建阴影和深度效果
    #import "GPUImageDissolveBlendFilter.h"             // 溶解效果
    #import "GPUImageKuwaharaFilter.h"                  // 桑原(Kuwahara)滤波,水粉画的模糊效果;处理时间比较长,慎用
    #import "GPUImageKuwaharaRadius3Filter.h"           // 桑原半径
    #import "GPUImageVignetteFilter.h"                  // 晕影,形成黑色圆形边缘,突出中间图像的效果
    #import "GPUImageGaussianBlurFilter.h"              // 高斯模糊
    #import "GPUImageGaussianBlurPositionFilter.h"      // 高斯模糊,指定某个区域的size,中心和半径进行模糊处理
    #import "GPUImageGaussianSelectiveBlurFilter.h"     // 高斯模糊,除指定圆形区域外的部分模糊
    #import "GPUImageOverlayBlendFilter.h"              // 叠加,通常用于创建阴影效果
    #import "GPUImageDarkenBlendFilter.h"               // 加深混合,通常用于重叠类型
    #import "GPUImageLightenBlendFilter.h"              // 减淡混合,通常用于重叠类型
    #import "GPUImageSwirlFilter.h"                     // 漩涡,中间形成卷曲的画面
    #import "GPUImageSourceOverBlendFilter.h"           // 源混合
    #import "GPUImageColorBurnBlendFilter.h"            // 色彩加深混合
    #import "GPUImageColorDodgeBlendFilter.h"           // 色彩减淡混合
    #import "GPUImageScreenBlendFilter.h"               // 屏幕包裹,通常用于创建亮点和镜头眩光
    #import "GPUImageExclusionBlendFilter.h"            // 排斥混合
    #import "GPUImageDifferenceBlendFilter.h"           // 差异混合,通常用于创建更多变动的颜色
    #import "GPUImageSubtractBlendFilter.h"             // 差值混合,通常用于创建两个图像之间的动画变暗模糊效果
    #import "GPUImageHardLightBlendFilter.h"            // 强光混合,通常用于创建阴影效果
    #import "GPUImageSoftLightBlendFilter.h"            // 柔光混合
    #import "GPUImageColorBlendFilter.h"                // 颜色混合
    #import "GPUImageHueBlendFilter.h"                  // hue混合
    #import "GPUImageSaturationBlendFilter.h"           // 饱和度混合
    #import "GPUImageLuminosityBlendFilter.h"           // 光度混合
    #import "GPUImageCropFilter.h"                      // 裁剪
    #import "GPUImageGrayscaleFilter.h"                 // 灰度
    #import "GPUImageTransformFilter.h"                 // 形状变化
    #import "GPUImageChromaKeyBlendFilter.h"            // 浓度键混合
    #import "GPUImageHazeFilter.h"                      // 朦胧
    #import "GPUImageLuminanceThresholdFilter.h"        // 亮度阈值
    #import "GPUImagePosterizeFilter.h"                 // 色调分离,形成噪点效果
    #import "GPUImageBoxBlurFilter.h"                   // 盒装模糊
    #import "GPUImageAdaptiveThresholdFilter.h"         // 自适应阈值
    #import "GPUImageUnsharpMaskFilter.h"               // 模糊遮罩
    #import "GPUImageBulgeDistortionFilter.h"           // 凸起,鱼眼效果
    #import "GPUImagePinchDistortionFilter.h"           // 凹陷,凹面镜效果
    #import "GPUImageCrosshatchFilter.h"                // 交叉线阴影,形成黑白网状画面
    #import "GPUImageCGAColorspaceFilter.h"             // CGA色彩滤镜,形成黑、浅蓝、紫色块的画面
    #import "GPUImagePolarPixellateFilter.h"            // 两端像素化
    #import "GPUImageStretchDistortionFilter.h"         // 伸展变形,哈哈镜效果
    #import "GPUImagePerlinNoiseFilter.h"               // 柏林噪点,花边噪点
    #import "GPUImageJFAVoronoiFilter.h"                // Voronoi 图
    #import "GPUImageVoronoiConsumerFilter.h"           // Voronoi 图
    #import "GPUImageMosaicFilter.h"                    // 马赛克
    #import "GPUImageTiltShiftFilter.h"                 // 条纹模糊
    #import "GPUImage3x3ConvolutionFilter.h"            // 3x3卷积,高亮大色块变黑,加亮边缘、线条等
    #import "GPUImageEmbossFilter.h"                    // 浮雕效果
    #import "GPUImageCannyEdgeDetectionFilter.h"        // Canny边缘检测算法(白边,黑内容,有点漫画的反色效果)
    #import "GPUImageThresholdEdgeDetectionFilter.h"    // 阈值边缘检测
    #import "GPUImageMaskFilter.h"                      // 遮罩
    #import "GPUImageHistogramFilter.h"                     // 色彩直方图,显示在图片上
    #import "GPUImageHistogramGenerator.h"                  // 色彩直方图产生器
    #import "GPUImageHistogramEqualizationFilter.h"         // 均衡直方图
    #import "GPUImagePrewittEdgeDetectionFilter.h"          // 普瑞维特(Prewitt)边缘检测(效果与Sobel差不多,貌似更平滑)
    #import "GPUImageXYDerivativeFilter.h"                  // XYDerivative边缘检测,画面以蓝色为主,绿色为边缘,带彩色
    #import "GPUImageHarrisCornerDetectionFilter.h"         // Harris角点检测,会有绿色小十字显示在图片角点处
    #import "GPUImageAlphaBlendFilter.h"                    // 透明混合,通常用于在背景上应用前景的透明度
    #import "GPUImageNormalBlendFilter.h"                   // 正常混合效果
    #import "GPUImageNonMaximumSuppressionFilter.h"         // 非最大抑制,只显示亮度最高的像素,其他为黑
    #import "GPUImageRGBFilter.h"                           // RGB
    #import "GPUImageMedianFilter.h"                        // 中间值,边缘模糊效果
    #import "GPUImageBilateralFilter.h"                     // 双边模糊
    #import "GPUImageCrosshairGenerator.h"                  // 十字产生器
    #import "GPUImageToneCurveFilter.h"                     // 色调曲线
    #import "GPUImageNobleCornerDetectionFilter.h"          // Noble角点检测,检测点更多
    #import "GPUImageShiTomasiFeatureDetectionFilter.h"     // ShiTomasi角点检测,与上差别不大
    #import "GPUImageErosionFilter.h"                       // 侵蚀边缘模糊,变黑白
    #import "GPUImageRGBErosionFilter.h"                    // RGB侵蚀边缘模糊,有色彩
    #import "GPUImageDilationFilter.h"                      // 扩展边缘模糊,变黑白
    #import "GPUImageRGBDilationFilter.h"                   // RGB扩展边缘模糊,有色彩
    #import "GPUImageOpeningFilter.h"                       // 黑白色调模糊
    #import "GPUImageRGBOpeningFilter.h"                    // 彩色模糊
    #import "GPUImageClosingFilter.h"                       // 黑白色调模糊,暗色会被提亮
    #import "GPUImageRGBClosingFilter.h"                    // 彩色模糊,暗色会被提亮
    #import "GPUImageColorPackingFilter.h"                  // 色彩丢失,模糊(类似监控摄像效果)
    #import "GPUImageSphereRefractionFilter.h"              // 球形折射,图像倒立
    #import "GPUImageMonochromeFilter.h"                    // 单色
    #import "GPUImageOpacityFilter.h"                       // 不透明度
    #import "GPUImageHighlightShadowFilter.h"               // 阴影高亮
    #import "GPUImageFalseColorFilter.h"                    // 色彩替换(替换亮部和暗部色彩)
    #import "GPUImageHSBFilter.h"                           // HSB又称HSV(色相、饱和度、亮度)
    #import "GPUImageHueFilter.h"                           // 色相
    #import "GPUImageGlassSphereFilter.h"                   // 玻璃球效果
    #import "GPUImageLookupFilter.h"                        // lookup(可自定义色板进行滤镜效果渲染)
    #import "GPUImageAmatorkaFilter.h"                      // Amatorka
    #import "GPUImageMissEtikateFilter.h"                   // MissEtikate
    #import "GPUImageSoftEleganceFilter.h"                  // SoftElegance
    #import "GPUImageAddBlendFilter.h"                      // 通常用于创建两个图像之间的动画变亮模糊效果
    #import "GPUImageDivideBlendFilter.h"                   // 通常用于创建两个图像之间的动画变暗模糊效果
    #import "GPUImagePolkaDotFilter.h"                      // 像素圆点花样
    #import "GPUImageLocalBinaryPatternFilter.h"            // 图像黑白化,并有大量噪点
    #import "GPUImageLanczosResamplingFilter.h"             // Lanczos重取样,模糊效果
    #import "GPUImageAverageColor.h"                        // 平均色值
    #import "GPUImageSolidColorGenerator.h"                 // 纯色
    #import "GPUImageLuminosity.h"                          // 亮度
    #import "GPUImageAverageLuminanceThresholdFilter.h"     // 像素色值亮度平均,图像黑白(有类似漫画效果)
    #import "GPUImageWhiteBalanceFilter.h"                  // 白平衡
    #import "GPUImageChromaKeyFilter.h"                     // 色度键
    #import "GPUImageLowPassFilter.h"                       // 低通滤波器
    #import "GPUImageHighPassFilter.h"                      // 高通滤波器
    #import "GPUImageMotionDetector.h"                      // 动作检测
    #import "GPUImageHalftoneFilter.h"                      // 点染,图像黑白化,由黑点构成原图的大致图形
    #import "GPUImageThresholdedNonMaximumSuppressionFilter.h"  // 与GPUImageNonMaximumSuppressionFilter.h相比,像素丢失更多
    #import "GPUImageHoughTransformLineDetector.h"          // 线条检测
    #import "GPUImageParallelCoordinateLineTransformFilter.h"   // 平行线坐标
    #import "GPUImageThresholdSketchFilter.h"               // 阈值素描
    #import "GPUImageLineGenerator.h"                       // 线条产生器
    #import "GPUImageLinearBurnBlendFilter.h"               // 现状模糊
    #import "GPUImageTwoInputCrossTextureSamplingFilter.h"  // 双输入交叉纹理
    #import "GPUImagePoissonBlendFilter.h"                  // 泊松分布
    #import "GPUImageMotionBlurFilter.h"                    // 移动模糊
    #import "GPUImageZoomBlurFilter.h"                      // 缩放模糊
    #import "GPUImageLaplacianFilter.h"                     // Laplacian
    #import "GPUImageiOSBlurFilter.h"                       // ios 模糊
    #import "GPUImageLuminanceRangeFilter.h"                // 光度范围
    #import "GPUImageDirectionalNonMaximumSuppressionFilter.h"  // 方向无最大抑制
    #import "GPUImageDirectionalSobelEdgeDetectionFilter.h"     // Sobel 边缘检测
    #import "GPUImageSingleComponentGaussianBlurFilter.h"       // 单一组件的高斯模糊
    #import "GPUImageThreeInputFilter.h"                        // 三输入滤镜
    #import "GPUImageWeakPixelInclusionFilter.h"                // 弱像素内含物
    

    如有错误恳请留言纠正

    今天就先整理这么多,以后会持续更新的。去写我的第三个小程序啦!

    相关文章

      网友评论

          本文标题:GPUImage 学习一(开篇:简单实现滤镜效果)

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