iOS-滤镜

最近在网上看了几篇大牛的博客,感觉还是有不少收获的,其中滤镜有的版本比较旧,我就自己整理了一些,毕竟人力有时而穷,所以有不当之处,请多指正。
  在iOS5.0之前这些算法基本全部要靠程序员编程实现,实现过程相当复杂。从iOS5.0开始苹果官方已经提供了Core Image框架来帮助开发者进行特效制作。
  滤镜:就是给图像添加效果

一、介绍
先来看一下滤镜使用过程中常用的基类对象:
1、CIContext:图像上下文,用于管理整个图片处理过程,不同的图形上下文将利用不同的图像处理硬件进行图像处理(在iOS中可以通过不同的方式创建图像上下文)。所有图像处理都是在一个CIContext 中完成的,这很像是一个Core Image处理器或是OpenGL的上下文。滤镜对象输出的图像,并不是合成之后的图像,需要使用图像处理的上下文,合并输出图像。
2、CIFilter:滤镜类,用来创建滤镜,图像属性进行细节处理的类,他对所有的像素进行操作,用键-值(KVC)来设置。滤镜有很多种,比如鲜艳程度滤镜,色彩反转滤镜,剪裁滤镜等等。每种滤镜有不同的参数设置。
3、CIImage:Core Image框架中的图像类型,主要用于输入和输出图像。这个类保存图像数据。它可以从UIImage、图像文件、或者是像素数据中构造出来。
CGImageRef:图像中的数据
4、效果介绍 100+效果可以通过attributes查找需要设置的参数内容
按效果分类:
kCICategoryDistortionEffect 扭曲效果,比如bump、旋转、hole
kCICategoryGeometryAdjustment 几何开着调整,比如仿射变换、平切、透视转换
kCICategoryCompositeOperation 合并,比如源覆盖(source over)、最小化、源在顶(source atop)、色彩混合模式
kCICategoryHalftoneEffect Halftone效果,比如screen、line screen、hatched
kCICategoryColorAdjustment 色彩调整,比如伽马调整、白点调整、曝光
kCICategoryColorEffect 色彩效果,比如色调调整、posterize
kCICategoryTransition 图像间转换,比如dissolve、disintegrate with mask、swipe
kCICategoryTileEffect 瓦片效果,比如parallelogram、triangle
kCICategoryGenerator 图像生成器,比如stripes、constant color、checkerboard
kCICategoryGradient 渐变,比如轴向渐变、仿射渐变、高斯渐变
kCICategoryStylize 风格化,比如像素化、水晶化
kCICategorySharpen 锐化、发光
kCICategoryBlur 模糊,比如高斯模糊、焦点模糊、运动模糊
按使用场景分类:
kCICategoryStillImage 用于静态图像
kCICategoryVideo 用于视频
kCICategoryInterlaced 用于交错图像
kCICategoryNonSquarePixels 用于非矩形像素
kCICategoryHighDynamicRange 用于HDR

二、使用
1.查询效果分类里面的效果
filterNamesInCategory:
2.查询效果的属性
[CIFilter filterWithName:XXX].attributes
/*
查询步骤:
1.查询 效果分类中 包含什么效果:filterNamesInCategory:
(1)按住command 点击CIFilter 进入接口文件 找到第128行-148行全部都是 效果分类
(2)选择其中某一个分类 NSLog -> [CIFilter filterNamesInCategory:刚才拷贝的分类]; -> 打印出来的 是这个分类包含的所有 效果 -> 拷贝选择其中的某一个效果
2.查询 使用的效果中 可以设置什么属性(KVC) attributes
NSLog -> [CIFilter filterWithName:刚才拷贝选择其中的某一个效果].attributes ->得到这个滤镜所有可以设置的属性
*/
// 通过分类查找这个分类里面所有的滤镜效果
// 分类的名字:CIFilter自己提供了分类的名字
// [CIFilter filterNamesInCategory:@”“];
NSLog(@”%@”,[CIFilter filterNamesInCategory:kCICategoryHighDynamicRange]);
// 查询可以设置那些参数
// [CIFilter filterWithName:@”CIBumpDistortion”].attributes

NSLog(@"%@",[CIFilter filterWithName:@"CIAdditionCompositing"].attributes);

使用步骤:
1、实例CIImage。需要先把CIImage转换成CGImageRef,再转换成CIImage
2、创建CIFilter滤镜,并给滤镜设置属性(KVC)
3、创建CIContext上下文
4、合并滤镜输出的图像,得到一个合并之后的图像
5、赋给UIImage对象进行显示
6、如果想使用滤镜链,可以再次叠加效果

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

三、在工程中的具体代码
这里就举一个例子吧:

#import "ViewController.h"

@interface ViewController ()<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
    UIImageView *imageView;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    imageView = [[UIImageView alloc]initWithFrame:self.view.frame];
    imageView.contentMode = UIViewContentModeScaleAspectFit;
    [self.view addSubview:imageView];

    for (int i = 0 ; i < 2; i++) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(80*i+60, 100, 60, 30);
        [button setTitle:@"TICK" forState:UIControlStateNormal];
        button.showsTouchWhenHighlighted = YES;
        button.backgroundColor = [UIColor purpleColor];
        button.tag = 100+i;
        [self.view addSubview:button];
    }

    UIButton *button = [self.view viewWithTag:100];
    [button addTarget:self action:@selector(doit:) forControlEvents:UIControlEventTouchUpInside];
 UIButton *button2 = [self.view viewWithTag:103];
    [button2 addTarget:self action:@selector(addAngle) forControlEvents:UIControlEventTouchUpInside];
    /* 怎样查询效果的分类? 1.查询效果分类中包含什么效果:filterNamesInCategory: (1)按住command 点击CIFilter 进入接口文件,找到该接口文件第128行-148行,这些全部都是效果分类 (2)选择其中某一个分类 NSLog -> [CIFilter filterNamesInCategory:刚才拷贝的分类]; -> 打印出来的 是这个分类包含的所有 效果 -> 拷贝选择其中的某一个效果 2.怎样查询使用的效果中可以设置什么属性? 关键词:(KVC) attributes NSLog -> [CIFilter filterWithName:刚才拷贝选择其中的某一个效果].attributes ->得到这个滤镜所有可以设置的属性 使用步骤: 1、需要添加滤镜的原图 2、需要添加滤镜,并设置滤镜(根据查询到的属性来设置) 3、把滤镜输出的图像和滤镜合并 CIContext -> 得到一个合成之后的图像 4、展示 */
// 通过分类查找这个分类里面所有的滤镜效果
// 分类的名字:CIFilter自己提供了分类的名字
// [CIFilter filterNamesInCategory:@""];
    NSLog(@"%@",[CIFilter filterNamesInCategory:kCICategoryHighDynamicRange]);
// 查询可以设置那些参数
// [CIFilter filterWithName:@"CIBumpDistortion"].attributes

    NSLog(@"%@",[CIFilter filterWithName:@"CIAdditionCompositing"].attributes);
    ![某个效果的分类](http://img.blog.csdn.net/20160324213525805)
    ![某个效果的分类的属性](http://img.blog.csdn.net/20160324213648260)
   }

- (void)addAngle{
    // 1、输入的原图,在这里需要先得到CGImage,在转换成CIImage
    CIImage *inputImage = [CIImage imageWithCGImage:imageView.image.CGImage];
    // 2、滤镜
    CIFilter *filter = [CIFilter filterWithName:@"CIAdditionCompositing"];
    // kCIInputImageKey通过打印可以设置的属性中得知可以设置inputImage,在接口文件里面得到的一个key
    [filter setValue:inputImage forKey:kCIInputImageKey];

    [filter setValue:[CIImage imageWithCGImage:imageView.image.CGImage] forKey:kCIInputBackgroundImageKey];

    // 3、CIContext合并原图和滤镜效果
    CIImage *outputImage = filter.outputImage;
    // 创建图像操作的上下文
    CIContext *context = [CIContext contextWithOptions:nil];
    // 合并成一个包含原图和滤镜效果的图像
    // 1、image:滤镜输出的图像
    // 2、fromRect:合成之后图像的尺寸:图像.extent
    CGImageRef imageRef = [context createCGImage:outputImage fromRect:outputImage.extent];
    imageView.image = [UIImage imageWithCGImage:imageRef];
}

- (void)doit:(UIButton *)sender{
    UIImagePickerController *picker = [[UIImagePickerController alloc]init];
    picker.delegate = self;
    [self presentViewController:picker animated:YES completion:nil];

}

//选择完图片调用
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
    UIImage *chooseImage = info[UIImagePickerControllerOriginalImage];
    imageView.image = chooseImage;
    [self dismissViewControllerAnimated:YES completion:nil];

}

//再次添加滤镜形成滤镜链
- (void)addFilterLinkerWithImage:(CIImage *)image{

    CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone"];
    [filter setValue:image forKey:kCIInputImageKey];
    CIContext *contex = [CIContext contextWithOptions:nil];
    CGImageRef imageRef = [contex createCGImage:filter.outputImage fromRect:filter.outputImage.extent];
    imageView.image = [UIImage imageWithCGImage:imageRef];

    //把添加好滤镜效果的图片保存到相册
// 不可以直接保存outputImage,因为这是一个没有把滤镜效果和原图合成的图像
    UIImageWriteToSavedPhotosAlbum(imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
    NSLog(@"保存成功");
}

还有其他的效果,实现的方法和例子相似,在查询效果分类和效果分类的属性的时候容易混淆,还请大家多留意哦,有兴趣的话去试试吧!

你可能感兴趣的:(ios,滤镜,CoreImage,iOS9之后的滤镜)