效果圖:
一直想研究一下圖片濾鏡怎么實(shí)現(xiàn)的,抽空研究了一下丧凤,下面是實(shí)現(xiàn)部分呼胚,代碼都有注釋,灰常的詳細(xì)息裸,希望可以幫到正在開發(fā)濾鏡 圖片處理相關(guān)的碼友_蝇更,先把demo地址放出來 ,如果比較著急的可以直接看demo:
demo地址
https://github.com/wxh794708907/YJYYImageFilter.git
代碼實(shí)踐
//
// ViewController.m
// YJYYImageFilter
//
// Created by 遇見遠(yuǎn)洋 on 17/2/17.
// Copyright ? 2017年 遇見遠(yuǎn)洋. All rights reserved.
//
#import "ViewController.h"
#define ScreenWidth [self.view bounds].size.width
#define ScreenHeight [self.view bounds].size.height
@interface ViewController ()<UIPickerViewDelegate,UIPickerViewDataSource>
/** 數(shù)據(jù)源 */
@property(nonatomic,strong) NSArray *dataArray;
/** 顯示數(shù)據(jù) */
@property(nonatomic,strong) NSArray *pickerData;
/** 展示圖 */
@property(nonatomic,strong) UIImageView *showImageV;
/** 原始圖片 */
@property(nonatomic,strong) UIImage *originalImage;
/** pickView */
@property(nonatomic,strong) UIPickerView *pickView;
/** 亮度inputBrightness */
@property(nonatomic,strong) NSMutableArray *inputBrightness;
/** 飽和度inputSaturation */
@property(nonatomic,strong) NSMutableArray *inputSaturation;
/** 對比度inputContrast */
@property(nonatomic,strong) NSMutableArray *inputContrast;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//展示視圖
[self.view addSubview:self.showImageV];
//pickView
[self.view addSubview:self.pickView];
}
#pragma mark - pickView數(shù)據(jù)源以及代理方法
#pragma mark -
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 4;
}
//返回每個組件上的行數(shù)
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
switch (component) {
case 0:
return self.dataArray.count;
break;
case 1:
return self.inputBrightness.count;
break;
case 2:
return self.inputContrast.count;
break;
case 3:
return self.inputSaturation.count;
break;
default:
return 0;
break;
}
}
//設(shè)置每行顯示的內(nèi)容
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
switch (component) {
case 0:
return [self.pickerData objectAtIndex:row];
break;
case 1:
return [NSString stringWithFormat:@"%@",self.inputBrightness[row]];
break;
case 2:
return [NSString stringWithFormat:@"%@",self.inputContrast[row]];
break;
case 3:
return [NSString stringWithFormat:@"%@",self.inputSaturation[row]];
break;
default:
return nil;
break;
}
}
//選中某一行時調(diào)用
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
switch (component) {
case 0://濾鏡
[self filterImageWithfilterName:self.dataArray[row]];
break;
case 1://亮度
[self colorControlsWithSaturation:1.f brightness:[self.inputBrightness[row] floatValue] contrast:1.f];
break;
case 2://對比度
[self colorControlsWithSaturation:1.f brightness:0 contrast:[self.inputContrast[row] floatValue]];
break;
case 3://飽和度
[self colorControlsWithSaturation:[self.inputSaturation[row] floatValue] brightness:0 contrast:1.f];
break;
default:
break;
}
}
#pragma mark - 對圖片進(jìn)行濾鏡處理
#pragma mark -
// 懷舊 --> CIPhotoEffectInstant
// 單色 --> CIPhotoEffectMono
// 黑白 --> CIPhotoEffectNoir
// 褪色 --> CIPhotoEffectFade
// 色調(diào) --> CIPhotoEffectTonal
// 沖印 --> CIPhotoEffectProcess
// 歲月 --> CIPhotoEffectTransfer
// 鉻黃 --> CIPhotoEffectChrome
- (void )filterImageWithfilterName:(NSString *)name{
if ([name isEqualToString:@"OriginalImage"]) {//原圖
self.showImageV.image = [UIImage imageNamed:@"original"];
return;
}
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//將UIImage轉(zhuǎn)換成CIImage
CIImage *ciImage = [[CIImage alloc] initWithImage:self.originalImage];
//創(chuàng)建濾鏡
CIFilter *filter = [CIFilter filterWithName:name keysAndValues:kCIInputImageKey, ciImage, nil];
//已有的值不改變呼盆,其他的設(shè)為默認(rèn)值
[filter setDefaults];
//獲取繪制上下文
CIContext *context = [CIContext contextWithOptions:nil];
//渲染并輸出CIImage
CIImage *outputImage = [filter outputImage];
//創(chuàng)建CGImage句柄
CGImageRef cgImage = [context createCGImage:outputImage fromRect:[outputImage extent]];
//獲取圖片
UIImage *image = [UIImage imageWithCGImage:cgImage];
//釋放CGImage句柄
CGImageRelease(cgImage);
dispatch_async(dispatch_get_main_queue(), ^{
self.showImageV.image = image;
});
});
}
/**
* 調(diào)整圖片飽和度, 亮度, 對比度
* @param saturation 飽和度 默認(rèn)為1
* @param brightness 亮度: -1.0 ~ 1.0 默認(rèn)是0
* @param contrast 對比度 默認(rèn)為1
*
*/- (void)colorControlsWithSaturation:(CGFloat)saturation
brightness:(CGFloat)brightness
contrast:(CGFloat)contrast{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *inputImage = [[CIImage alloc] initWithImage:self.originalImage];
CIFilter *filter = [CIFilter filterWithName:@"CIColorControls"];
[filter setValue:inputImage forKey:kCIInputImageKey];
[filter setValue:@(saturation) forKey:@"inputSaturation"];
[filter setValue:@(brightness) forKey:@"inputBrightness"];
[filter setValue:@(contrast) forKey:@"inputContrast"];
CIImage *result = [filter valueForKey:kCIOutputImageKey];
CGImageRef cgImage = [context createCGImage:result fromRect:[result extent]];
UIImage *resultImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
dispatch_async(dispatch_get_main_queue(), ^{
self.showImageV.image = resultImage;
});
});
}
#pragma mark - 懶加載部分
#pragma mark -
- (NSArray *)dataArray {
if (!_dataArray) {
_dataArray = [NSArray arrayWithObjects:
@"OriginalImage",
@"CIPhotoEffectInstant",
@"CIPhotoEffectMono",
@"CIPhotoEffectNoir",
@"CIPhotoEffectFade",
@"CIPhotoEffectTonal",
@"CIPhotoEffectProcess",
@"CIPhotoEffectTransfer",
@"CIPhotoEffectChrome",
nil];
}
return _dataArray;
}
- (NSArray *)pickerData {
if (!_pickerData) {
_pickerData = [NSArray arrayWithObjects:
@"原圖",
@"懷舊",
@"單色",
@"黑白",
@"褪色",
@"色調(diào)",
@"沖印",
@"歲月",
@"鉻黃",
nil];
}
return _pickerData;
}
- (NSMutableArray *)inputBrightness {//亮度
if (!_inputBrightness) {
_inputBrightness = [NSMutableArray arrayWithArray:@[@-1,@-0.5,@0,@0.5,@1]];
}
return _inputBrightness;
}
- (NSMutableArray *)inputSaturation {//對比度
if (!_inputSaturation) {
_inputSaturation = [NSMutableArray arrayWithArray:@[@0,@1,@2,@3,@4]];
}
return _inputSaturation;
}
- (NSMutableArray *)inputContrast {//飽和度
if (!_inputContrast) {
_inputContrast = [NSMutableArray arrayWithArray:@[@0,@0.5,@1,@1.5,@2]];
}
return _inputContrast;
}
- (UIImageView *)showImageV {
if (!_showImageV) {
_showImageV = [[UIImageView alloc]initWithImage:self.originalImage];
_showImageV.contentMode = UIViewContentModeScaleAspectFit;
_showImageV.frame = CGRectMake(0, 0, 300, 300);
_showImageV.center = CGPointMake(self.view.center.x, self.view.center.y - 100);
}
return _showImageV;
}
- (UIImage *)originalImage {
if (!_originalImage) {
_originalImage = [UIImage imageNamed:@"original"];
}
return _originalImage;
}
- (UIPickerView *)pickView {
if (!_pickView) {
_pickView = [[UIPickerView alloc]initWithFrame:CGRectMake(0, ScreenHeight - 300, ScreenWidth, 300)];
_pickView.dataSource = self;
_pickView.delegate = self;
//默認(rèn)選中
[self.pickView selectRow:0 inComponent:0 animated:YES];
[self.pickView selectRow:2 inComponent:1 animated:YES];
[self.pickView selectRow:2 inComponent:2 animated:YES];
[self.pickView selectRow:1 inComponent:3 animated:YES];
}
return _pickView;
}
建議大家運(yùn)行一下demo來看一下效果年扩,為了方便大家查看效果,我已經(jīng)使用pickView來將效果展示出來访圃,我覺得還是比較方便的厨幻,有什么不懂得 一看代碼就懂了,這里我還是按照慣例總結(jié)一下吧:
濾鏡的實(shí)現(xiàn)步驟:
- 將原始的UIImage對象轉(zhuǎn)換成CIImage的對象
- 創(chuàng)建濾鏡
- 獲取繪制上下文
- 渲染并輸出CIImage對象
- 創(chuàng)建CGImage句柄
- 將CGImageRef對象轉(zhuǎn)換為UIImage對象
- 釋放CGImage句柄(這里要注意 內(nèi)存釋放)
圖片飽和度腿时、亮度等設(shè)置我就不寫步驟了况脆,其實(shí)原理是一樣的,都是通過創(chuàng)建一個濾鏡 設(shè)置不同的值來實(shí)現(xiàn)效果批糟,建議大家看看代碼吧格了,不是很難。