• iOS滤镜功能


    一、iOS自带滤镜

    1.CoreImage

    使用苹果自带的CoreImage框架对图片进行处理,用CoreImage框架里的CIFilter对图片进行滤镜处理,

    首先我们应该了解下CoreImage框架能够对图像进行那些处理和拥有哪些特效。

    苹果给我们提供了将近200中滤镜效果

    // 这里我们可以看到总共有多少种滤镜
    
     NSArray *filterNames = [CIFilter filterNamesInCategory:@"CICategoryBuiltIn"];       
    NSLog(@"总共有%ld种滤镜效果:%@",filterNames.count,filterNames); //以一个具体分类中的滤镜信息 NSArray* filters = [CIFilter filterNamesInCategory:kCICategoryDistortionEffect]; for (NSString* filterName in filters) { NSLog(@"filter name:%@",filterName); // 我们可以通过filterName创建对应的滤镜对象 CIFilter* filter = [CIFilter filterWithName:filterName]; NSDictionary* attributes = [filter attributes]; // 获取属性键/值对(在这个字典中我们可以看到滤镜的属性以及对应的key) NSLog(@"filter attributes:%@",attributes); }

    然后我们还可以进入苹果iOS官方文档中具体看看效果到底是什么样子的Core Image Filter Reference

    可以看到CoreImage中的CIFilter效果确实很多,分很多种类别,每个分类中又有多个效果

     

    2.滤镜怎么实现

    CoreImage框架提供三个API来实现滤镜效果

    CIContext:核心API,来管理所有的图片处理操作。

    CIFilter:过滤器,通过在创建CIFilter时需要传入不同的参数即可创建不同类型的过滤器。

    CIImage:它代表 Core Image 过滤器处理的图片,CIFilter过滤器的输入图片,输出图片都由该CIImage代表。

    CIContext:创建分三种方式,因为采用基于GPU的CIContext将可以获得更好的性能,因此,

    一般建议创建基于GPU的CIContext,但基于GPU的CIContext对象无法跨应用访问,这个问题需要注意

     //1.创建基于CPU的CIContext对象    
     self.context = [CIContext contextWithOptions:
        [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
     forKey:kCIContextUseSoftwareRenderer]];
    
        //2.创建基于GPU的CIContext对象 
     self.context = [CIContext contextWithOptions: nil];
    
        //3.创建基于OpenGL优化的CIContext对象,可获得实时性能
    self.context = [CIContext contextWithEAGLContext:[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]];
    
    // 将UIImage转换成CIImage
        CIImage *ciImage = [[CIImage alloc] initWithImage:[UIImage imageNamed:@"WechatIMG1.jpeg"]];
        // 创建滤镜
        CIFilter *filter = [CIFilter filterWithName:_dataSourse[indexPath.row]
                                      keysAndValues:kCIInputImageKey, ciImage, nil];
        [filter setDefaults];
    
        // 获取绘制上下文
        CIContext *context = [CIContext contextWithOptions:nil];
        // 渲染并输出CIImage
        CIImage *outputImage = [filter outputImage];
        // 创建CGImage句柄
        CGImageRef cgImage = [self.context createCGImage:outputImage
                                          fromRect:[outputImage extent]];
        imageview.image = [UIImage imageWithCGImage:cgImage];
        // 释放CGImage句柄
        CGImageRelease(cgImage);

    二、GPUImage实现滤镜

    1. GPUImage

    GPUImage是现在做滤镜最主流的开源框架,没有之一。作者BradLarson基于openGL对图片处理单元进行封装,

    提供出GPUImageFilter基类,配合shader,常用滤镜都拿下不是问题。

    1.1、安装(请参考这个 https://www.jianshu.com/p/4d419a88ecce

    (1):首先下载GPUImagehttps://github.com/BradLarson/GPUImage

    (2):解压后,在framework 目录下,打开 GPUImage.xcodeproj  工程

    下载完成打开文件有件

     2、GPUImage的使用

    使用GPUImage自带的滤镜,GPUImage自带的滤镜有很多种这里举例一种

     GPUImageBrightnessFilter *disFilter = [[GPUImageBrightnessFilter alloc] init];
            //设置美白参数
            disFilter.brightness = 0.2;
            //设置要渲染的区域
            [disFilter forceProcessingAtSize:image.size];
            
            [disFilter useNextFrameForImageCapture];
            
            //获取数据源
            GPUImagePicture *stillImageSource = [[GPUImagePicture alloc]initWithImage:image];
            
            //添加上滤镜
            [stillImageSource addTarget:disFilter];
            
            //开始渲染
            [stillImageSource processImage];
            //获取渲染后的图片
            UIImage *newImage = [disFilter imageFromCurrentFramebuffer];
            return newImage;

    另外就是根据纹理自定义滤镜来处理图片,纹理图片可有设计提供,另外纹理的叠加还需要研究

    #import "GPUImageTwoInputFilter.h"
    
    #import "GPUImage.h"
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface DhGPUImageQingXinFilter : GPUImageTwoInputFilter
    
    @end
    @interface GPUImageQingXinFilter : GPUImageFilterGroup
    {
        GPUImagePicture *imageSource ;
        GPUImagePicture *imageSource2 ;
    }
    @end
    NS_ASSUME_NONNULL_END
    #import "DhGPUImageQingXinFilter.h"
    
    #import "GPUImageLookupFilter.h"
    #import "GPUImageFilter.h"
    //自定义shader
    
    NSString *const GPUImageQingXinFilterString = SHADER_STRING
    (
     precision lowp float;
     
     varying highp vec2 textureCoordinate;
     
     uniform sampler2D inputImageTexture;
     uniform sampler2D inputImageTexture2;
     void main()
     {
         
         vec3 texel = texture2D(inputImageTexture, textureCoordinate).rgb;
         
         texel = vec3(
                      texture2D(inputImageTexture2, vec2(texel.r, .16666)).r,
                      texture2D(inputImageTexture2, vec2(texel.g, .5)).g,
                      texture2D(inputImageTexture2, vec2(texel.b, .83333)).b);
         gl_FragColor = vec4(texel, 1.0);
     }
     );
    
    @implementation DhGPUImageQingXinFilter
    - (id)init;
    {
        if (!(self = [super initWithFragmentShaderFromString:GPUImageQingXinFilterString]))
        {
            return nil;
        }
        
        return self;
    }
    @end
    
    @implementation GPUImageQingXinFilter
    
    
    - (id)init
    {
        if (!(self = [super init]))
        {
            return nil;
        }
        //  清新
        
        UIImage *image2 = [UIImage imageNamed:@"camera_filter_overlay_map.png"];
        UIImage *image = [UIImage imageNamed:@"camera_filter_sierra_map"];
        
        
        imageSource = [[GPUImagePicture alloc] initWithImage:image];
        DhGPUImageQingXinFilter *filter = [[DhGPUImageQingXinFilter alloc] init];
        
        [self addFilter:filter];
        
        [imageSource addTarget:filter atTextureLocation:1];
        [imageSource processImage];
        
        imageSource2 = [[GPUImagePicture alloc] initWithImage:image2];
        DhGPUImageQingXinFilter *filter2 = [[DhGPUImageQingXinFilter alloc] init];
        [filter addTarget:filter2];
        [imageSource2 addTarget:filter2];
        [imageSource2 processImage];
        [self addFilter:filter2];
        
        self.initialFilters = [NSArray arrayWithObjects:filter, nil];
        self.terminalFilter = filter;
        
        return self;
    }
    - (void)dealloc
    {
    #if !OS_OBJECT_USE_OBJC
        if (imageCaptureSemaphore != NULL)
        {
            dispatch_release(imageCaptureSemaphore);
        }
    #endif
        
    }
    @end

     

     
  • 相关阅读:
    PHP获取某年第几周的开始日期和结束日期
    Java多线程(一)
    Java多线程学习
    使用反射实现 webdriver page 类
    PageObjects 设计模式
    Selenium WebDriver 工作原理
    Selenium2.0 Webdriver 随笔
    Selenium-Grid2 配置RemoteWebDriver
    Java多线程基础(二)
    Java多线程基础(一)
  • 原文地址:https://www.cnblogs.com/ljcgood66/p/11521077.html
Copyright © 2020-2023  润新知