• IOS开发之滤镜 CIImage、CIFilter


       滤镜这个词也许大家会耳生,特别是男生,不是歧视哦,只是你不经常用而已,那么肯定就有人说,我是女生怎么了,我也没有听过这个词啊,是不是过滤代码的?(你真是想多了-3-!)

      但是你会对一下的几个词比较耳熟,比如说anglelababy代言的美颜相机,还有你们经常使用的美图秀秀,你以为你照下来就是那么美若天仙的样子?本人表示再也不相信网上的美女了,忽然觉得咱班花都挺好。哈哈;

       好了,话不多说,我们来进入今天的主题:滤镜

    •  介绍

             框架介绍

             类的介绍

             效果介绍

    • 使用

            使用步骤

            滤镜属性

    • 滤镜链的使用

       

       1. *框架介绍

        (1) CoreImage

        (2) 是一个图像框架 他是基于OpenGL顶层创建的一个框架

        (3) 它是利用GPU机遇硬件加速来处理图像

        (4) CoreImage中有很多滤镜

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

        (6)而且滤镜可以连接起来组成一个滤镜链 把滤镜效果叠加起来处理图像

      2.类的介绍

       (1)CIImage 保存图像数据的类  可以和UIImage去转换

                CGImgeRef 图像里面的数据‘

        (2)CIFilter:滤镜类  对滤镜对象进行设置的时候是通过键值编码来设置的(KVC)

        (3)CIContext :上下文 是实现对图像处理的具体对象 ——》滤镜对象输出的对象并不是合成之后的对象、需要使用图像处理的上下文 合并输出的图像

      3.效果介绍

           100+效果可以通过可以通过Attribute这个属性得到你先要在滤镜上面展示的效果(详细不列举,列举明天早上就起不来了)

    *使用

        使用步骤:

          1、有一个CIImage的对象  不能直接把UIIMage转成CIImage  应该先把UIIMage转成CGImgeRef再转成CIImage

          2、创建一个滤镜的对象,设置他的参数(KVC)

          3、创建CIContext上下文

          4、合并滤镜输出的图像 ——  合并之后会得到一个图像

          5、赋值给UIImageView显示出来

          6、如果想要继续添加滤镜可以继续循环

       

       滤镜属性:

           注意:我们这里是直接查询到自己需要的属性,并不需要去记,不然就会有一种纪英汉大字典的感觉

         1.查询效果分类里面的效果

               filterNamesInCategory:

         2.查询效果的属性

             [CIFilter filterWithName:XXX].attributes

     

    下面老夫为大家上代码:(不给你整点料,你是不知道我文武全才)

       先做准备工作,实在是剧情需要,不然看不出特效:两个button,一个pickViewController(因为要访问到你的相册)、一个ImageView

    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor whiteColor];
        self.navigationController.navigationBarHidden = YES;
        
        
        imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 200, 500, 600)];
        imageView.contentMode = UIViewContentModeScaleAspectFill;
        imageView.backgroundColor = [UIColor grayColor];
        [self.view addSubview:imageView];
        
        
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(0, 0, 50, 50);
        button.backgroundColor = [UIColor grayColor];
        [button addTarget:self action:@selector(tap:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
        
    //
        UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom];
        button1.frame = CGRectMake(100, 100, 100, 100);
        [button1 setTitle:@"TICK" forState:UIControlStateNormal];
        button1.backgroundColor = [UIColor brownColor];
        [button1 addTarget:self action:@selector(addEffect) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button1];
        
      }
    
    - (void)tap:(UIButton *) sender{
        UIImagePickerController *picker = [[UIImagePickerController alloc]init];
        picker.delegate = self;
    //    picker.sourceType = 默认是照片
        [self presentViewController:picker animated:YES completion:nil];
        
    
    }
    
    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
        [self dismissViewControllerAnimated:YES completion:nil];
        UIImage *image = info[UIImagePickerControllerOriginalImage];
    //    得到的照片显示在视图上
        imageView.image = image;
    //    NSLog(@"%@",info);
    }

    现在先讲一下滤镜的大概流程,我觉得一张图就足矣表达:

    - (void)addFilter{
        
        //   1. 需要有一个输入的原图
        CIImage *inputImage = [CIImage imageWithCGImage:imageView.image.CGImage];
        //   2. 需要一个滤镜
        CIFilter *filter = [CIFilter filterWithName:@"CIBumpDistortion"];
        //     通过打印可以设置的属性里面 得到可以设置 inputImage ——》在接口文件里面查找得到的key

    // 这里我们使用的是KVC的方式给filter设置属性 [filter setValue:inputImage forKey:kCIInputImageKey]; // 设置凹凸的效果半径 越大越明显 [filter setValue:@500 forKey:kCIInputRadiusKey]; // CIVector :表示 X Y 坐标的一个类 // 设置中心点的 [filter setValue:[CIVector vectorWithX:200 Y:200] forKey:kCIInputCenterKey]; // 3.有一个CIContext的对象去合并原图和滤镜效果 CIImage *outputImage = filter.outputImage; // 创建一个图像操作的上下文 CIContext *context = [CIContext contextWithOptions:nil]; // 把原图和滤镜合并起来 包含原图和滤镜效果的图像 /** * Image : 合成之后的图像 * fromRect: 合成之后图像的尺寸: 图像.extent */ CGImageRef imageRef = [context createCGImage:outputImage fromRect:outputImage.extent]; imageView.image = [UIImage imageWithCGImage:imageRef]; }

    注意 :这里有几个坑啊:1。需要原图的时候我们需要的是一个CIImage Class的对象,不是CGIMage的对象,很多人都写错了,所以我们只能转化把CGImage转成CIImage

                                     2. 我们所需要的滤镜属性以及特效的类都只能NSLog出来,而且这里特别容易混淆,具体方法如下:

                                              1.查询 效果分类中 包含什么效果:filterNamesInCategory:

                                                 (1)按住command 点击CIFilter 进入接口文件 找到第128行-148行全部都是 效果分类

                                                 (2)选择其中某一个分类 NSLog -> [CIFilter filterNamesInCategory:刚才拷贝的分类]; -> 打印出来的 是这个分类包含的所有 效果  -> 拷贝选择其中的某一个效果

                                              2.查询 使用的效果中 可以设置什么属性(KVC) attributes

                                                     NSLog -> [CIFilter filterWithName:刚才拷贝选择其中的某一个效果].attributes ->得到这个滤镜所有可以设置的属性

    你要是还理不清的话:1.求神保佑你蒙对了(可能性为负数) 2.如图所示,多多参悟

             

           大概流程是:先CIFiliter  ——》 点进去得到category中的其中一个 ——》使用    [CIFilter filterNamesInCategory:刚才拷贝的分类]   方法nslog出所需要的类;  ————》  在类里有很多的子类 随便copy一个  ——》  [CIFilter filterWithName:刚才拷贝选择其中的某一个效果].attributes  获得到所有可设置的属性 ————》  使用KVC的方法设置属性  setValue:Forkey:(注意:这里的key也需要进CIFilter里去找和你所选的属性类似的Key,在CIFilter的165-191行

     *滤镜链:就是滤镜的嵌套组合使用

        

    #pragma mark===滤镜链
    //再次添加滤镜 形成滤镜链
    - (void)addfilterLinkerWithImage:(CIImage *)image{
        CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone"];
        [filter setValue:image forKey:kCIInputImageKey];
        
        [filter setValue:@0.5 forKey:kCIInputIntensityKey];
        CIContext *context = [CIContext contextWithOptions:nil];
        CGImageRef imageRef = [context createCGImage:filter.outputImage fromRect:filter.outputImage.extent];
        imageView.image = [UIImage imageWithCGImage:imageRef];
        
    //保存图片到相册  不可以直接保存outputImage 因为这是一个没有合成的图像
        UIImageWriteToSavedPhotosAlbum(imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    
    }

    当然 ,你也可以一直添加,到最后一步再把滤镜和原图结合起来,这样更省代码-3-!

  • 相关阅读:
    软件工程作业------分析文本文档,统计出现频率最多的十个单词
    关于IBOutlet的生命周期
    重装iTunes 错误代码42401 解决办法
    关于在多个UItextield切换焦点
    关于如何使用代码触发 UIButton的Unwind Segue
    NSFileManager在初始化文件的时候一不留神就进入陷阱
    Xcode的编辑利器Xvim,如何去掉烦人工具栏和文件路径
    __weak 和 __strong 还有Autorelease的用法
    关于NSFetchedResultsController的一些用法
    关于MVC模型的NSNotification用法
  • 原文地址:https://www.cnblogs.com/Biaoac/p/5317012.html
Copyright © 2020-2023  润新知