最近在研究自定义相机,关于滤镜的组合与叠加,于是利用GPUImage开发了一个demo,用于实现多个滤镜的组合与即时调节,主要用于给设计师进行自定义滤镜的开发
.h文件
#import
#import "GPUImage.h"
#import "GPUImageBeautifyFilter.h" // 自定义美颜滤镜
@interfaceGPUViewController :UIViewController
{
GPUImageView*gpuImageView;
GPUImagePicture*gpuImagePicture;
GPUImageView*_imageView;
GPUImageStillCamera*_stillCamera;
GPUImageBeautifyFilter*_beautifyFilter;//美颜滤镜
GPUImageSaturationFilter *_saturationF;//饱和度滤镜
GPUImageContrastFilter *_contrastF;//对比度滤镜
GPUImageBrightnessFilter *_brightnessF;//亮度滤镜
GPUImageLevelsFilter *_levelsF;//色阶滤镜
GPUImageExposureFilter *_expisureF;//曝光度滤镜
GPUImageRGBFilter *_rgbF;//RGB滤镜
GPUImageHueFilter *_hueF;//色度滤镜
GPUImageWhiteBalanceFilter *_whiteBalandeF;//白平衡滤镜
GPUImageSharpenFilter *_sharpenF;//锐化滤镜
GPUImageGammaFilter *_gammaF;//伽马线滤镜
GPUImageToneCurveFilter *_toneCurveF;//色调曲线滤镜
GPUImageSepiaFilter *_sepiaF;//怀旧滤镜
GPUImageGaussianBlurFilter *_gaussianBlurF;//高斯模糊滤镜
GPUImagePinchDistortionFilter *_pinchDistortionF;//哈哈镜滤镜
}
@end
.m文件
#import "GPUViewController.h"
@interface GPUViewController ()
@property(strong,nonatomic)GPUImageFilterGroup *myFilterGroup;
@end
@implementationGPUViewController
- (void)viewDidAppear:(BOOL)animated
{
[superviewDidAppear:animated];
}
- (void)viewDidLoad {
[super viewDidLoad];
CGFloat width = self.view.bounds.size.width;
CGFloat height = self.view.bounds.size.height;
self.myFilterGroup = [[GPUImageFilterGroup alloc] init];
// GPUImageView 用来显示相机捕获的画面
_imageView= [[GPUImageViewalloc]initWithFrame:CGRectMake(0,88,ScreenWidth,ScreenWidth*1920/1080)];
_imageView.fillMode = kGPUImageFillModeStretch;
[_imageView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(focusTap:)]];
[self.view addSubview:_imageView];
_stillCamera = [[GPUImageStillCamera alloc] initWithSessionPreset:AVCaptureSessionPreset1920x1080 cameraPosition:AVCaptureDevicePositionBack];
_stillCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
[_stillCamera addTarget:self.myFilterGroup];
_brightnessF = [[GPUImageBrightnessFilter alloc] init];
_saturationF = [[GPUImageSaturationFilter alloc]init];
_contrastF = [[GPUImageContrastFilter alloc] init];
_levelsF = [[GPUImageLevelsFilter alloc] init];
_expisureF = [[GPUImageExposureFilter alloc] init];
_rgbF = [[GPUImageRGBFilter alloc] init];
_hueF = [[GPUImageHueFilter alloc] init];
_whiteBalandeF = [[GPUImageWhiteBalanceFilter alloc] init];
_sharpenF = [[GPUImageSharpenFilter alloc] init];
_gammaF= [[GPUImageGammaFilter alloc] init];
_toneCurveF= [[GPUImageToneCurveFilter alloc] init];
_sepiaF= [[GPUImageSepiaFilter alloc] init];
_gaussianBlurF= [[GPUImageGaussianBlurFilter alloc] init];
_pinchDistortionF= [[GPUImagePinchDistortionFilter alloc] init];
[self addGPUImageFilter:_saturationF];
[self addGPUImageFilter:_contrastF];
[self addGPUImageFilter:_brightnessF];
[self addGPUImageFilter:_levelsF];
[self addGPUImageFilter:_expisureF];
[self addGPUImageFilter:_rgbF];
[self addGPUImageFilter:_hueF];
[self addGPUImageFilter:_whiteBalandeF];
[self addGPUImageFilter:_sharpenF];
[self addGPUImageFilter:_gammaF];
[self addGPUImageFilter:_toneCurveF];
[self addGPUImageFilter:_sepiaF];
[self addGPUImageFilter:_gaussianBlurF];
// [self addGPUImageFilter:_pinchDistortionF];
[self.myFilterGroup addTarget:_imageView];
// 捕获镜头画面
[_stillCamera startCameraCapture];
for(inti =0; i <13; i++) {
UILabel*label = [[UILabelalloc]initWithFrame:CGRectMake(0,ScreenHeight-100- i *30,100,30)];
label.textColor = [UIColor redColor];
label.font = [UIFont systemFontOfSize:20];
// 调解滤镜值
UISlider*slider = [[UISlideralloc]initWithFrame:CGRectMake(100,ScreenHeight-100- i *30, width -100,30)];
if(i ==0) {
slider.maximumValue=2;
slider.minimumValue=0;
slider.value=1;
label.text=@"饱和度";
}
if(i ==1) {
slider.maximumValue=4;
slider.minimumValue=0;
slider.value=1;
label.text=@"对比度";
}
if(i ==2) {
slider.maximumValue=1;
slider.minimumValue= -1;
slider.value=0;
label.text=@"亮度";
}
if(i ==3) {
slider.maximumValue=1;
slider.minimumValue=0;
slider.value=0;
label.text=@"色阶";
}
if(i ==4) {
slider.maximumValue=2;
slider.minimumValue=0;
slider.value=1;
label.text=@"曝光";
}
if(i ==5) {
label.text=@"RGB";
for(intj =0; j <3; j ++) {
CGFloatrgbW = (ScreenWidth-100) /3;
UISlider*RGBslider = [[UISlideralloc]initWithFrame:CGRectMake(100+ rgbW * j,ScreenHeight-100- i *30, rgbW,30)];
RGBslider.maximumValue=10;
RGBslider.minimumValue=0;
RGBslider.value=1;
RGBslider.tag=200+ j;
[RGBslideraddTarget:self action:@selector(slider2ValueChanged:) forControlEvents:UIControlEventValueChanged];
[self.viewaddSubview:RGBslider];
}
slider.hidden=YES;
}
if(i ==6) {
slider.maximumValue=360;
slider.minimumValue=0;
slider.value=90;
label.text=@"色度";
}
if(i ==7) {
slider.maximumValue=7500;
slider.minimumValue=2500;
slider.value=5000;
label.text=@"白平衡";
}
if(i ==8) {
slider.maximumValue=4;
slider.minimumValue= -4;
slider.value=0;
label.text=@"锐化";
}
if(i ==9) {
slider.maximumValue=3;
slider.minimumValue=0;
slider.value=1;
label.text=@"伽马线";
}
if(i ==10) {
slider.maximumValue=1;
slider.minimumValue=0;
slider.value=0.5;
label.text=@"色调曲线";
}
if(i ==11) {
slider.maximumValue=3;
slider.minimumValue=0;
slider.value=0.05;
label.text=@"怀旧";
}
if(i ==12) {
slider.maximumValue=4;
slider.minimumValue= -4;
slider.value=0;
label.text=@"高斯模糊";
}
if(i ==13) {
slider.maximumValue=2;
slider.minimumValue= -2;
slider.value=0.5;
label.text=@"凹面镜";
}
slider.tag=100+ i;
[slideraddTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
[self.viewaddSubview:slider];
[self.viewaddSubview:label];
}
// 拍照按钮
UIButton *takeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
takeBtn.frame=CGRectMake(self.view.bounds.size.width/2.0-80, height -80,60,60);
[takeBtnsetTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
[takeBtnsetTitle:@"拍照" forState:UIControlStateNormal];
[takeBtnaddTarget:self action:@selector(takeBtnAction:) forControlEvents:UIControlEventTouchUpInside];
[self.viewaddSubview:takeBtn];
// 切换镜头按钮
UIButton *lensBtn = [UIButton buttonWithType:UIButtonTypeCustom];
lensBtn.frame=CGRectMake(self.view.bounds.size.width/2.0+20, height -80,60,60);
[lensBtnsetTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
[lensBtnsetTitle:@"后置" forState:UIControlStateNormal];
[lensBtnsetTitle:@"前置" forState:UIControlStateSelected];
lensBtn.selected=YES;
[lensBtnaddTarget:self action:@selector(lensBtnAction:) forControlEvents:UIControlEventTouchUpInside];
[self.viewaddSubview:lensBtn];
}
// 聚焦操作
- (void)focusTap:(UITapGestureRecognizer*)tap {
CGPointtouchPoint = [taplocationInView:tap.view];
[self layerAnimationWithPoint:touchPoint];
touchPoint =CGPointMake(touchPoint.x/ tap.view.bounds.size.width, touchPoint.y/ tap.view.bounds.size.height);
/*以下是相机的聚焦和曝光设置,前置不支持聚焦但是可以曝光处理,后置相机两者都支持,下面的方法是通过点击一个点同时设置聚焦和曝光,当然根据需要也可以分开进行处理
*/
if ([_stillCamera.inputCamera isExposurePointOfInterestSupported] && [_stillCamera.inputCamera isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) {
NSError*error;
if([_stillCamera.inputCameralockForConfiguration:&error]) {
[_stillCamera.inputCamerasetExposurePointOfInterest:touchPoint];
[_stillCamera.inputCamera setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
if([_stillCamera.inputCamera isFocusPointOfInterestSupported] && [_stillCamera.inputCamera isFocusModeSupported:AVCaptureFocusModeAutoFocus])
{
[_stillCamera.inputCamerasetFocusPointOfInterest:touchPoint];
[_stillCamera.inputCamera setFocusMode:AVCaptureFocusModeAutoFocus];
}
[_stillCamera.inputCamera unlockForConfiguration];
}else{
NSLog(@"ERROR = %@", error);
}
}
}
// 焦点动画
- (void)layerAnimationWithPoint:(CGPoint)point {
if (_focusLayer) {
CALayer*focusLayer =_focusLayer;
focusLayer.hidden=NO;
[CATransaction begin];
[CATransaction setDisableActions:YES];
[focusLayersetPosition:point];
focusLayer.transform = CATransform3DMakeScale(2.0f,2.0f,1.0f);
[CATransaction commit];
CABasicAnimation *animation = [ CABasicAnimation animationWithKeyPath: @"transform" ];
animation.toValue = [ NSValue valueWithCATransform3D: CATransform3DMakeScale(1.0f,1.0f,1.0f)];
animation.delegate=self;
animation.duration=0.3f;
animation.repeatCount=1;
animation.removedOnCompletion=NO;
animation.fillMode = kCAFillModeForwards;
[focusLayeraddAnimation: animationforKey:@"animation"];
}
}
- (void)sliderValueChanged:(UISlider*)sender{
switch(sender.tag) {
case100:
_saturationF.saturation= sender.value;
break;
case101:
_contrastF.contrast= sender.value;
break;
case102:
_brightnessF.brightness= sender.value;
break;
case103:
[_levelsF setRedMin:sender.value gamma:1 max:1 minOut:0 maxOut:1];
[_levelsF setGreenMin:sender.value gamma:1 max:1 minOut:0 maxOut:1];
[_levelsF setBlueMin:sender.value gamma:1 max:1 minOut:0 maxOut:1];
break;
case104:
_expisureF.exposure= sender.value;
break;
case105:
break;
case106:
_hueF.hue= sender.value;
break;
case107:
[_whiteBalandeF setTemperature:sender.value];
break;
case108:
_sharpenF.sharpness= sender.value;
break;
case109:
_gammaF.gamma= sender.value;
break;
case110:
[_toneCurveF setBlueControlPoints:[NSArray arrayWithObjects:[NSValue valueWithCGPoint:CGPointMake(0.0, 0.0)], [NSValue valueWithCGPoint:CGPointMake(0.5, [(UISlider *)sender value])], [NSValue valueWithCGPoint:CGPointMake(1.0, 0.75)], nil]];
break;
case111:
[_sepiaFsetIntensity:sender.value];
break;
case112:
[_gaussianBlurF setBlurRadiusInPixels:sender.value];
break;
case113:
[_pinchDistortionF setScale:sender.value];
break;
default:
break;
}
}
- (void)slider2ValueChanged:(UISlider*)sender{
switch(sender.tag) {
case200:
_rgbF.red= sender.value;
break;
case201:
_rgbF.green= sender.value;
break;
case202:
_rgbF.blue= sender.value;
break;
default:
break;
}
}
- (void)takeBtnAction:(UIButton*)sender{
// _stillCamera 要添加至少一个 filter target,否则捕获的图片是 null
[_stillCamera capturePhotoAsImageProcessedUpToFilter:self.myFilterGroup withCompletionHandler:^(UIImage *processedImage, NSError *error) {
NSLog(@"image:%@",processedImage);
NSLog(@"error:%@",error);
UIImageWriteToSavedPhotosAlbum(processedImage,nil,nil,nil);
}];
}
- (void)lensBtnAction:(UIButton*)sender{
[_stillCamera rotateCamera];
sender.selected= !sender.selected;
}
//将滤镜加在FilterGroup中并且设置初始滤镜和末尾滤镜
- (void)addGPUImageFilter:(GPUImageOutput*)filter{
[self.myFilterGroup addFilter:filter];
GPUImageOutput *newTerminalFilter = filter;
NSInteger count = self.myFilterGroup.filterCount;
if(count ==1)
{
self.myFilterGroup.initialFilters=@[newTerminalFilter];
self.myFilterGroup.terminalFilter= newTerminalFilter;
}else
{
GPUImageOutput
NSArray*initialFilters =self.myFilterGroup.initialFilters;
[terminalFilteraddTarget:newTerminalFilter];
self.myFilterGroup.initialFilters=@[initialFilters[0]];
self.myFilterGroup.terminalFilter= newTerminalFilter;
}
}
@end
直接复制就可以使用啦~