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-!

 

posted @ 2016-03-24 20:25  Biaoac  阅读(2722)  评论(0编辑  收藏  举报