iOS開發 濾鏡效果

Core Image

利用Quartz 2D我們可以繪製各類圖形、圖像,功能確實強大。用過photoshop的朋友都知道,使用photoshop可以製作各種濾鏡特效,那麼在iOS中能否實現濾鏡呢?在iOS5.0之前這些算法基本全部要靠程序員編程實現,實現過程相當複雜。從iOS5.0開始蘋果官方已經提供了Core Image框架來幫助開發者進行特效製作。

先來看一下濾鏡使用過程中常用的基類對象:

CIContext:圖像上下文,用於管理整個圖片處理過程,不同的圖形上下文將利用不同的圖像處理硬件進行圖像處理(在iOS中可以通過不同的方式創建圖像上下文,例如可以創建基於CPU的圖像上下方、創建基於GPU的圖像上下方以及創建OpenGL優化過的圖像上下文)。

CIFilter:圖像處理濾鏡,每種濾鏡有不同的參數設置。

CIImage:Core Image框架中的圖像類型,主要用於輸入和輸出圖像。

在使用濾鏡之前我們先要弄清平臺主要支持哪些濾鏡,以及這些濾鏡的方法和參數如何設置,此時不妨使用下面的方法進行打印查看:

#pragma mark 查看所有內置濾鏡
-(void)showAllFilters{
    NSArray *filterNames=[CIFilter filterNamesInCategory:kCICategoryBuiltIn];
    for (NSString *filterName in filterNames) {
        CIFilter *filter=[CIFilter filterWithName:filterName];
        NSLog(@"\rfilter:%@\rattributes:%@",filterName,[filter attributes]);
    }
}

在iOS7中打印會發現有127中濾鏡,如果我們把每種濾鏡都介紹一遍恐怕用幾章內容也很難介紹詳細,事實上也沒有這個必要。這些濾鏡使用方法是類似的,只是參數設置有所區別。在iOS文檔中可以搜索“core image filter reference”一節的內容,裏面有每種濾鏡的詳細介紹和圖片使用效果。

使用Core Image框架創建濾鏡效果一般分爲以下幾步:

1.創建圖像上下文CIContext

2.創建濾鏡CIFilter

3.創建過濾原圖片CIImage

4.調用CIFilter的setValue: forKey:方法爲濾鏡指定源圖片

5.設置濾鏡參數【可選】

6.取得輸出圖片顯示或保存

大家都知道在美圖秀秀中有一個“增強”功能,利用它可以調整照片的飽和度、亮度、對比度,其實在Core Image中也有這樣一款濾鏡,下面就以顏色濾鏡來演示一下Core Image中濾鏡的使用。

//
//  KCMainViewController.m
//  CoreImage
//
//  Created by Kenshin Cui on 14-3-17.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import "KCMainViewController.h"
#define CONSTROLPANEL_FONTSIZE 12

@interface KCMainViewController ()<UINavigationControllerDelegate,UIImagePickerControllerDelegate>{
    UIImagePickerController *_imagePickerController;//系統照片選擇控制器
    UIImageView *_imageView;//圖片顯示控件
    CIContext *_context;//Core Image上下文
    CIImage *_image;//我們要編輯的圖像
    CIImage *_outputImage;//處理後的圖像
    CIFilter *_colorControlsFilter;//色彩濾鏡
}

@end

@implementation KCMainViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self initLayout];
}


#pragma mark 初始化佈局
-(void)initLayout{
    //初始化圖片選擇器
    _imagePickerController=[[UIImagePickerController alloc]init];
    _imagePickerController.delegate =self;

    //創建圖片顯示控件
    _imageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 64, 320, 502)];
    _imageView.contentMode=UIViewContentModeScaleAspectFit;
    [self.view addSubview:_imageView];
    
    //上方導航按鈕
    self.navigationItem.title=@"Enhance";
    self.navigationItem.leftBarButtonItem=[[UIBarButtonItem alloc]initWithTitle:@"Open" style:UIBarButtonItemStyleDone target:self action:@selector(openPhoto:)];
    self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc]initWithTitle:@"Save" style:UIBarButtonItemStyleDone target:self action:@selector(savePhoto:)];

    
    //下方控制面板
    UIView *controlView=[[UIView alloc]initWithFrame:CGRectMake(0, 450, 320, 118)];
//    controlView.alpha=0.2;
//    controlView.backgroundColor=[UIColor colorWithRed:46.0/255.0 green:178.0/255.0 blue:235.0/255.0 alpha:1];
    [self.view addSubview:controlView];
    //飽和度(默認爲1,大於飽和度增加小於1則降低)
    UILabel *lbSaturation=[[UILabel alloc]initWithFrame:CGRectMake(10, 10, 60, 25)];
    lbSaturation.text=@"Saturation";
    lbSaturation.font=[UIFont systemFontOfSize:CONSTROLPANEL_FONTSIZE];
    [controlView addSubview:lbSaturation];
    UISlider *sldStaturation=[[UISlider alloc]initWithFrame:CGRectMake(80, 10, 230, 30)];//注意UISlider高度雖然無法調整,很多朋友會說高度設置位0即可,事實上在iOS7中設置爲0後是無法拖動的
    [controlView addSubview:sldStaturation];
    sldStaturation.minimumValue=0;
    sldStaturation.maximumValue=2;
    sldStaturation.value=1;
    [sldStaturation addTarget:self action:@selector(changeStaturation:) forControlEvents:UIControlEventValueChanged];
    //亮度(默認爲0)
    UILabel *lbBrightness=[[UILabel alloc]initWithFrame:CGRectMake(10, 40, 60, 25)];
    lbBrightness.text=@"Brightness";
    lbBrightness.font=[UIFont systemFontOfSize:CONSTROLPANEL_FONTSIZE];
    [controlView addSubview:lbBrightness];
    UISlider *sldBrightness=[[UISlider alloc]initWithFrame:CGRectMake(80, 40, 230, 30)];
    [controlView addSubview:sldBrightness];
    sldBrightness.minimumValue=-1;
    sldBrightness.maximumValue=1;
    sldBrightness.value=0;
    [sldBrightness addTarget:self action:@selector(changeBrightness:) forControlEvents:UIControlEventValueChanged];
    //對比度(默認爲1)
    UILabel *lbContrast=[[UILabel alloc]initWithFrame:CGRectMake(10, 70, 60, 25)];
    lbContrast.text=@"Contrast";
    lbContrast.font=[UIFont systemFontOfSize:CONSTROLPANEL_FONTSIZE];
    [controlView addSubview:lbContrast];
    UISlider *sldContrast=[[UISlider alloc]initWithFrame:CGRectMake(80, 70, 230, 30)];
    [controlView addSubview:sldContrast];
    sldContrast.minimumValue=0;
    sldContrast.maximumValue=2;
    sldContrast.value=1;
    [sldContrast addTarget:self action:@selector(changeContrast:) forControlEvents:UIControlEventValueChanged];
    
    
    //初始化CIContext
    //創建基於CPU的圖像上下文
    //    NSNumber *number=[NSNumber numberWithBool:YES];
    //    NSDictionary *option=[NSDictionary dictionaryWithObject:number forKey:kCIContextUseSoftwareRenderer];
    //    _context=[CIContext contextWithOptions:option];
    _context=[CIContext contextWithOptions:nil];//使用GPU渲染,推薦,但注意GPU的CIContext無法跨應用訪問,例如直接在UIImagePickerController的完成方法中調用上下文處理就會自動降級爲CPU渲染,所以推薦現在完成方法中保存圖像,然後在主程序中調用
    //    EAGLContext *eaglContext=[[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES1];
    //    _context=[CIContext contextWithEAGLContext:eaglContext];//OpenGL優化過的圖像上下文
    
    //取得濾鏡
    _colorControlsFilter=[CIFilter filterWithName:@"CIColorControls"];

}
#pragma mark 打開圖片選擇器
-(void)openPhoto:(UIBarButtonItem *)btn{
    //打開圖片選擇器
    [self presentViewController:_imagePickerController animated:YES completion:nil];
}
#pragma mark 保存圖片
-(void)savePhoto:(UIBarButtonItem *)btn{
    //保存照片到相冊
    UIImageWriteToSavedPhotosAlbum(_imageView.image, nil, nil, nil);
    UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"Sytem Info" message:@"Save Success!" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    [alert show];
}

#pragma mark 圖片選擇器選擇圖片代理方法
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    //關閉圖片選擇器
    [self dismissViewControllerAnimated:YES completion:nil];
    //取得選擇圖片
    UIImage *selectedImage=[info objectForKey:UIImagePickerControllerOriginalImage];
    _imageView.image=selectedImage;
    //初始化CIImage源圖像
    _image=[CIImage imageWithCGImage:selectedImage.CGImage];
    [_colorControlsFilter setValue:_image forKey:@"inputImage"];//設置濾鏡的輸入圖片
}

#pragma mark 將輸出圖片設置到UIImageView
-(void)setImage{
    CIImage *outputImage= [_colorControlsFilter outputImage];//取得輸出圖像
    CGImageRef temp=[_context createCGImage:outputImage fromRect:[outputImage extent]];
    _imageView.image=[UIImage imageWithCGImage:temp];//轉化爲CGImage顯示在界面中
    
    CGImageRelease(temp);//釋放CGImage對象
}

#pragma mark 調整飽和度
-(void)changeStaturation:(UISlider *)slider{
    [_colorControlsFilter setValue:[NSNumber numberWithFloat:slider.value] forKey:@"inputSaturation"];//設置濾鏡參數
    [self setImage];
}

#pragma mark 調整亮度
-(void)changeBrightness:(UISlider *)slider{
    [_colorControlsFilter setValue:[NSNumber numberWithFloat:slider.value] forKey:@"inputBrightness"];
    [self setImage];
}

#pragma mark 調整對比度
-(void)changeContrast:(UISlider *)slider{
    [_colorControlsFilter setValue:[NSNumber numberWithFloat:slider.value] forKey:@"inputContrast"];
    [self setImage];
}
@end

運行效果:

CoreImageEffect

再次給大家強調一下:

  • 在上面的代碼中除了使用了基於GPU的圖像上下文(推薦方式),也創建了其他圖像上下文,儘管已經被註釋大家還是需要熟悉。
  • Core Image允許你一次給圖像或視頻幀疊加多種效果,同時Core Image還能保證強大的處理效率。
  • 和在使用Core Graphics繪圖一樣,UIKit中也封裝了一些方法直接轉換爲Core Image中的對象,例如UIImage對象可以直接調用CIImage屬性轉換爲CIImage類型。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章