使用过Photoshop的人对于滤镜(Filter)应该有很深刻的印象,那么滤镜到底是什么?维基百科关于滤镜的解释如下:
滤镜通常用于相机镜头作为调色、添加效果之用。如UV镜、偏振镜、星光镜、各种色彩滤光片。滤镜也是绘图软件中用于制造特殊效果的工具统称,以Photoshop为例,它拥有风格化、画笔描边、模糊、扭曲、锐化、视频、素描、纹理、像素化、渲染、艺术效果、其他等12个滤镜。
在iOS中滤镜的API是指Core Image框架定义好的,并且非常重要。
iOS有90多种滤镜,而Mac OS X 10.8提供了120多种滤镜。滤镜数量很多,而且又有很多参数和属性使用起来有点麻烦。下面介绍一下滤镜的使用流程,滤镜使用流程可以分成以下3个步骤。
(1) 创建滤镜CIFilter对象;
(2) 设置滤镜参数;
(3) 输出结果。
实例代码如下:
CIContext *context = [CIContext contextWithOptions:nil]; CIImage *cImage = [CIImage imageWithCGImage:[imageView.image CGImage]]; CIFilter *invert = [CIFilter filterWithName:@"CIColorInvert"]; ① [invert setDefaults]; ② [invert setValue: cImage forKey:@"inputImage"]; ③ CIImage *result = [invert valueForKey:@"outputImage"]; ④
其中,第①行代码是创建滤镜对象,使用filterWithName:方法创建,还可以使用filterWithName:keysAndValues:方法创建,filterWithName:keysAndValues:在创建滤镜对象的同时可以设置其参数,使用实例代码如下:
CIFilter * invert = [CIFilter filterWithName:@"CIColorInvert" keysAndValues:@"inputImage", cImage, nil];
第②行代码[invert setDefaults]是设置滤镜的默认参数,由于每个滤镜都有很多参数,这些参数不需要一一设置,可以通过[invert setDefaults]语句设置默认值。
第③行代码[invert setValue: cImage forKey:@"inputImage"]是设置输入参数(inputImage),是必须要设定的参数。
第④行代码是获得输出的CIImage图像对象,可以调用滤镜的outputImage方法获得输出图像对象,代码如下所示。
CIImage * result = [invert outputImage];
下面通过一个具体的实例介绍滤镜使用,通过屏幕下方的两个按钮分别从两种不同的滤镜(旧色调和高斯模糊)。图3-8左所示,选择“旧色调”段后拖曳下面的滑块,可以改变色调强度。图3-8右所示,选择“高斯模糊”段后拖曳下面的滑块,改变高斯模糊半径。
![]() |
![]() |
图3-8 滤镜实例
首先使用Xcode选择Single View Application工程模板,创建一个FilterEffects工程。具体的UI设计过程不再赘述,重点看看代码部分。其中视图控制器类ViewController.h代码如下所示。
#import <UIKit/UIKit.h> @interface ViewController: UIViewController { int flag; // 0 为CISepiaTone 1 为CIGaussianBlur } @property (retain, nonatomic) IBOutlet UIImageView *imageView; @property (retain, nonatomic) IBOutlet UISlider *slider; @property (retain, nonatomic) UIImage *image; @property (retain, nonatomic) IBOutlet UILabel *label; - (IBAction)changeValue:(id)sender; - (IBAction)segmentSelected:(id)sender; @end
在上面的代码中int flag是定义的成员变量,用来记录单击了旧色调按钮还是单击了高斯模糊按钮,当单击旧色调按钮设置为0,当单击高斯模糊按钮设置为1。
视图控制器ViewController.m文件中操作旧色调filterSepiaTone方法代码如下所示。
- (void)filterSepiaTone { CIContext *context = [CIContext contextWithOptions:nil]; ① CIImage *cImage = [CIImage imageWithCGImage:[_image CGImage]]; ② CIImage *result; CIFilter *sepiaTone = [CIFilter filterWithName:@"CISepiaTone"]; ③ [sepiaTone setValue: cImage forKey: @"inputImage"]; ④ double value = [_slider value]; ⑤ NSString *text =[[NSString alloc] initWithFormat:@"旧色调 Intensity : %.2f",value]; _label.text = text; [text release]; [sepiaTone setValue: [NSNumber numberWithFloat: value] forKey: @"inputIntensity"]; ⑥ result = [sepiaTone valueForKey:@"outputImage"]; ⑦ CGImageRef imageRef = [context createCGImage:result fromRect: CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height)]; ⑧ UIImage *image = [[UIImage alloc] initWithCGImage:imageRef]; ⑨ _imageView.image = image; CFRelease(imageRef); ⑩ [image release]; flag = 0; }
在上述代码中,第①行CIContext *context=[CIContext contextWithOptions:nil]是创建CIContext对象,CIContext构造方法是一个NSDictionary类型参数,它规定了各种选项,包括颜色格式以及内容是否应该运行在CPU或是GPU上。本例是默认值,所以只需要传入nil。
第②行代码通过CGImage创建CIImage对象。第③行代码是创建CISepiaTone(旧色调)滤镜。第④行代码是设置滤镜的输入参数(inputImage)。第⑤行代码是获取滑块的值,默认情况下滑块的取值是0.0~1.0之间,而旧色调滤镜色调强度取值范围也是0.0~1.0之间,因此可以把滑块的值直接作为旧色调滤镜色调强度值使用。第⑥行代码是设置旧色调滤镜色调强度(inputIntensity)值。
第⑦行代码result=[sepiaTone valueForKey:@"outputImage"]是取得滤镜之后的图像对象,类型为CIImage。
第⑧行代码是使用CIContext的createCGImage:fromRect:方法创建CGImageRef对象。fromRect:部分参数是设置图像大小。第⑨行代码UIImage *image= [[UIImage alloc] initWithCGImage:imageRef]是通过CGImageRef创建UIImage图像对象,因为UIImage图像对象是可以放置在UIImageView控件上显示的。第⑩行代码CFRelease(imageRef)是释放CGImageRef对象。
视图控制器ViewController.m文件中操作高斯模糊filterGaussianBlur方法代码如下所示。
- (void)filterGaussianBlur { CIContext *context = [CIContext contextWithOptions:nil]; CIImage *cImage = [CIImage imageWithCGImage:[_image CGImage]]; CIImage *result; CIFilter *gaussianBlur=[CIFilter filterWithName:@"CIGaussianBlur"]; ① [gaussianBlur setValue: cImage forKey: @"inputImage"]; double value = [_slider value]; value *=10; ② NSString *text =[[NSString alloc] initWithFormat:@"高斯模糊 Radius : %.2f",value]; _label.text = text; [text release]; [gaussianBlur setValue: [NSNumber numberWithFloat: value] forKey: @"inputRadius"]; ③ result = [gaussianBlur valueForKey:@"outputImage"]; CGImageRef imageRef = [context createCGImage:result fromRect: CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height)]; UIImage *image = [[UIImage alloc] initWithCGImage:imageRef]; _imageView.image = image; CFRelease(imageRef); [image release]; flag = 1; }
filterGaussianBlur:方法与filterSepiaTone:方法非常相似,其中,第①行代码是创建高斯模糊滤镜(CIGaussianBlur)对象。第②行代码value *=10是将滑块取得的值乘10,使得其他的取值范围为0.0~10.0,这个取值将作为高斯模糊半径参数(Radius)。第③行代码是设置高斯模糊半径参数(Radius)取值,其中inputRadius是输入参数名。