iOS 滤镜


CIFilter实现滤镜效果

参考网址:CoreImage滤镜学习

CoreImage框架介绍

1.是一个图片框架 基于OpenGL顶层创建,底层用着色器来处理图像

2.利用GPU基于硬件加速来处理图像

3.CoreImage中有很多滤镜

4.它们能够一次给予一张图像或者视频帧多种视觉效果 -> 滤镜链

5.滤镜可以连接起来组成一个滤镜链 把滤镜效果叠加起来处理图像

CIFilter使用介绍
  1. CIFilter滤镜类中有很多的滤镜效果 这里不一一列举,可以按住command 点击CIFilter 进入接口文件 找到第128行-148行全部都是 效果分类

  2. 常用效果

    我们使用时需要先找到需要的效果类型 比如我们使用kCICategoryDistortionEffect失真的效果类型,有了效果类型我们需要找到里面我们需要的效果.

    NSLog -> [CIFilter filterNamesInCategory:刚才拷贝的分类];

    比如CIColorMonochrome ,然后就可以使用这个滤镜效果

    CIFilter *filter = [CIFilter filterWithName:@"CIColorMonochrome”];

    然后打印这个效果中包含了那些属性:

    NSLog(@"%@",filter.attributes);

    在里面我们可以看到好多属性,里面是多个字典的形式,找到我们想要修改的属性(key值) 然后在他对应的value里面查看一下他的属性类型,比如我们打印的CIColorMonochrome里面有一个inputColor,他是一个CIColor类型的,有默认值,这里我们写了一个CIColor来给他进行赋值.

    赋值时需要用kvc的方式:

    [filter setValue:colorforKey:kCIInputColorKey];

    DraggedImage

  3. 实现滤镜效果代码

    首先我们创建一个全局变量的UIImageView,然后让他初始化出来,这个就是我们要处理的图片 一般我们从手机相册中取出来:

    @interface ViewController ()<UINavigationControllerDelegate,UIImagePickerControllerDelegate>
    {
    UIImageView *imageView;
    }
    @end
    然后我们需要从相册中取出一张图片,保存起来:
    //跳转相册的触发方法
    - (void)doit{
    UIImagePickerController *vc = [[UIImagePickerController alloc]init];
    vc.delegate = self;
    [self presentViewController:vc animated:YES completion:nil];

    }
    //让图片显示在VC上面的方法
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
    {
    NSLog(@"%@",info);
    //获得选中的图像
    UIImage *chooseImage = info[UIImagePickerControllerOriginalImage];
    //先是在试图空间上
    imageView.image = chooseImage;
    [self dismissViewControllerAnimated:YES completion:nil];
    }

    接下来就是对图片进行滤镜处理:
    - (void)addColorFilter{
    //CIImage 保存图像数据的类
    CIImage inputImage = [CIImage imageWithCGImage:imageView.image.CGImage];
    //先打印NSLog(@"%@",[CIFilter filterNamesInCategory:kCICategoryDistortionEffect]);进去找到需要设置的属性(查询效果分类中都有什么效果) 可以设置什么效果
    //然后通过[CIFilter filterWithName:@""];找到属性 具体效果的属性
    //然后通过KVC的方式设置属性
    NSLog(@"%@",[CIFilter filterNamesInCategory:kCICategoryDistortionEffect]);
    /

    1.查询 效果分类中 包含什么效果:filterNamesInCategory:
    2.查询 使用的效果中 可以设置什么属性(KVC) attributes

     使用步骤
     1.需要添加滤镜的源图
    2.初始化一个滤镜 设置滤镜(根据查询到的属性来设置)
    3.把滤镜 输出的图像 和滤镜 合并 CIContext -> 得到一个合成之后的图像
    4.展示
    */
    //CIFilter 滤镜类 图片属性进行细节处理的类
    CIFilter *filter = [CIFilter filterWithName:@"CIColorMonochrome"];
    NSLog(@"%@",filter.attributes);
    //这个属性是必须赋值的,假如你处理的是图片的话
    [filter setValue:inputImage forKey:kCIInputImageKey];
    CIColor *color = [CIColor colorWithRed:1.000 green:0.759 blue:0.592 alpha:1];
    [filter setValue:color forKey:kCIInputColorKey];
    //CIContext 上下文是实现对图像处理的具体对象 用来把滤镜和图片合成成为一张图片 滤镜对象输出的图像并不是合成之后的图像,需要使用图片处理的上下文 合并输出图像
    CIContext *context = [CIContext contextWithOptions:nil];
    CIImage *outPutImage = filter.outputImage;
    //CGImageRef->图像中的数据
    CGImageRef image = [context createCGImage:outPutImage fromRect:outPutImage.extent];
    imageView.image = [UIImage imageWithCGImage:image];
    }

    注意:

    对滤镜进行赋值之后图片就有了,但是我们这个时候拿出这个图片的时候发现他并没有发生变化,因为它只是单一进行了滤镜处理,还没有和原图片进行一个糅合。使用CIContext找到上下文对他进行糅合:

    //extent得到图像的尺寸 合并一个包含源图 滤镜效果的图片
    //1 滤镜输出的图像 2.合成之后图像的尺寸 图像.extent
    CGImageRef imageRef = [context createCGImage:outPutImage fromRect:outPutImage.extent];
    注意:

    假如你的图片消失了,请检查一下,第一步获取图片的时候一定要获得图片的CGImage再来来获取,不要直接使用imageView.image.CGImage。

  4. 滤镜链:

    在给一张图片添加多种滤镜效果的时候,我们把它称为滤镜链,我们再添加滤镜链的时候,就是把图片添加一层滤镜,然后,和原图片糅合处理,然后在处理之后的图片上再添加一层滤镜,并不是直接给一张图片添加了两层路径,所以称为滤镜链。

    我们继续使用这个图片,在它添加第一层滤镜的时候做一些修改:

    //上接给效果属性赋值
    //把下面注释的给注释掉,然后添加一个方法
    //CIContext
    // CIContext *context = [CIContext contextWithOptions:nil];
    CIImage *outPutImage = filter.outputImage;
    [self addFilterLinkerWithImage:outPutImage];
    // CGImageRef image = [context createCGImage:outPutImage fromRect:outPutImage.extent];
    // imageView.image = [UIImage imageWithCGImage:image];
    //再次添加滤镜 -> 形成滤镜链
    - (void)addFilterLinkerWithImage:(CIImage *)image
    {
    CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone"];
    [filter setValue:image forKey:kCIInputImageKey];
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef resultImage = [context createCGImage:filter.outputImage fromRect:filter.outputImage.extent];
    imageView.image = [UIImage imageWithCGImage:resultImage];
    //把添加好滤镜效果的图片 保存到相册
    //不可以直接保存 outputImage -> 这是一个没有吧滤镜效果和源图合成的图像
    UIImageWriteToSavedPhotosAlbum(imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    }
    //保存图片回调
    - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
    {
    NSLog(@"保存成功");
    }

    这样就是一个双重的滤镜效果,同时保存到了相册.


系统自带简单的滤镜效果