购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.3 滤镜

使用过Photoshop的人对于滤镜(Filter)应该有很深刻的印象,那么滤镜到底是什么?维基百科关于滤镜的解释如下:

滤镜通常用于相机镜头作为调色、添加效果之用。如UV镜、偏振镜、星光镜、各种色彩滤光片。滤镜也是绘图软件中用于制造特殊效果的工具统称,以Photoshop为例,它拥有风格化、画笔描边、模糊、扭曲、锐化、视频、素描、纹理、像素化、渲染、艺术效果、其他等12个滤镜。

在iOS中滤镜的API是指Core Image框架定义好的,并且非常重要。

3.3.1 使用滤镜

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.3.2 实例:旧色调和高斯模糊滤镜

下面通过一个具体的实例介绍滤镜使用,通过屏幕下方的两个按钮分别从两种不同的滤镜(旧色调和高斯模糊)。图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是输入参数名。 d2j84nUKjX+fkgQ5Wj7CMPSAt92wVrGN9qkJLfb6aHgZLcFXS4y0RPCn49TTc3oM

点击中间区域
呼出菜单
上一章
目录
下一章
×