一、iOS自带滤镜
1.CoreImage
使用苹果自带的CoreImage框架对图片进行处理,用CoreImage框架里的CIFilter对图片进行滤镜处理,
首先我们应该了解下CoreImage框架能够对图像进行那些处理和拥有哪些特效。
苹果给我们提供了将近200中滤镜效果
// 这里我们可以看到总共有多少种滤镜 NSArray *filterNames = [CIFilter filterNamesInCategory:@"CICategoryBuiltIn"];
NSLog(@"总共有%ld种滤镜效果:%@",filterNames.count,filterNames); //以一个具体分类中的滤镜信息 NSArray* filters = [CIFilter filterNamesInCategory:kCICategoryDistortionEffect]; for (NSString* filterName in filters) { NSLog(@"filter name:%@",filterName); // 我们可以通过filterName创建对应的滤镜对象 CIFilter* filter = [CIFilter filterWithName:filterName]; NSDictionary* attributes = [filter attributes]; // 获取属性键/值对(在这个字典中我们可以看到滤镜的属性以及对应的key) NSLog(@"filter attributes:%@",attributes); }
然后我们还可以进入苹果iOS官方文档中具体看看效果到底是什么样子的Core Image Filter Reference
可以看到CoreImage中的CIFilter效果确实很多,分很多种类别,每个分类中又有多个效果
2.滤镜怎么实现
CoreImage框架提供三个API来实现滤镜效果
CIContext:核心API,来管理所有的图片处理操作。
CIFilter:过滤器,通过在创建CIFilter时需要传入不同的参数即可创建不同类型的过滤器。
CIImage:它代表 Core Image 过滤器处理的图片,CIFilter过滤器的输入图片,输出图片都由该CIImage代表。
CIContext:创建分三种方式,因为采用基于GPU的CIContext将可以获得更好的性能,因此,
一般建议创建基于GPU的CIContext,但基于GPU的CIContext对象无法跨应用访问,这个问题需要注意
//1.创建基于CPU的CIContext对象 self.context = [CIContext contextWithOptions: [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:kCIContextUseSoftwareRenderer]]; //2.创建基于GPU的CIContext对象 self.context = [CIContext contextWithOptions: nil]; //3.创建基于OpenGL优化的CIContext对象,可获得实时性能 self.context = [CIContext contextWithEAGLContext:[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]]; // 将UIImage转换成CIImage CIImage *ciImage = [[CIImage alloc] initWithImage:[UIImage imageNamed:@"WechatIMG1.jpeg"]]; // 创建滤镜 CIFilter *filter = [CIFilter filterWithName:_dataSourse[indexPath.row] keysAndValues:kCIInputImageKey, ciImage, nil]; [filter setDefaults]; // 获取绘制上下文 CIContext *context = [CIContext contextWithOptions:nil]; // 渲染并输出CIImage CIImage *outputImage = [filter outputImage]; // 创建CGImage句柄 CGImageRef cgImage = [self.context createCGImage:outputImage fromRect:[outputImage extent]]; imageview.image = [UIImage imageWithCGImage:cgImage]; // 释放CGImage句柄 CGImageRelease(cgImage);
二、GPUImage实现滤镜
1. GPUImage
GPUImage是现在做滤镜最主流的开源框架,没有之一。作者BradLarson基于openGL对图片处理单元进行封装,
提供出GPUImageFilter基类,配合shader,常用滤镜都拿下不是问题。
1.1、安装(请参考这个 https://www.jianshu.com/p/4d419a88ecce)
(1):首先下载GPUImagehttps://github.com/BradLarson/GPUImage
(2):解压后,在framework 目录下,打开 GPUImage.xcodeproj 工程
下载完成打开文件有件
2、GPUImage的使用
使用GPUImage自带的滤镜,GPUImage自带的滤镜有很多种这里举例一种
GPUImageBrightnessFilter *disFilter = [[GPUImageBrightnessFilter alloc] init]; //设置美白参数 disFilter.brightness = 0.2; //设置要渲染的区域 [disFilter forceProcessingAtSize:image.size]; [disFilter useNextFrameForImageCapture]; //获取数据源 GPUImagePicture *stillImageSource = [[GPUImagePicture alloc]initWithImage:image]; //添加上滤镜 [stillImageSource addTarget:disFilter]; //开始渲染 [stillImageSource processImage]; //获取渲染后的图片 UIImage *newImage = [disFilter imageFromCurrentFramebuffer]; return newImage;
另外就是根据纹理自定义滤镜来处理图片,纹理图片可有设计提供,另外纹理的叠加还需要研究
#import "GPUImageTwoInputFilter.h" #import "GPUImage.h" NS_ASSUME_NONNULL_BEGIN @interface DhGPUImageQingXinFilter : GPUImageTwoInputFilter @end @interface GPUImageQingXinFilter : GPUImageFilterGroup { GPUImagePicture *imageSource ; GPUImagePicture *imageSource2 ; } @end NS_ASSUME_NONNULL_END
#import "DhGPUImageQingXinFilter.h" #import "GPUImageLookupFilter.h" #import "GPUImageFilter.h" //自定义shader NSString *const GPUImageQingXinFilterString = SHADER_STRING ( precision lowp float; varying highp vec2 textureCoordinate; uniform sampler2D inputImageTexture; uniform sampler2D inputImageTexture2; void main() { vec3 texel = texture2D(inputImageTexture, textureCoordinate).rgb; texel = vec3( texture2D(inputImageTexture2, vec2(texel.r, .16666)).r, texture2D(inputImageTexture2, vec2(texel.g, .5)).g, texture2D(inputImageTexture2, vec2(texel.b, .83333)).b); gl_FragColor = vec4(texel, 1.0); } ); @implementation DhGPUImageQingXinFilter - (id)init; { if (!(self = [super initWithFragmentShaderFromString:GPUImageQingXinFilterString])) { return nil; } return self; } @end @implementation GPUImageQingXinFilter - (id)init { if (!(self = [super init])) { return nil; } // 清新 UIImage *image2 = [UIImage imageNamed:@"camera_filter_overlay_map.png"]; UIImage *image = [UIImage imageNamed:@"camera_filter_sierra_map"]; imageSource = [[GPUImagePicture alloc] initWithImage:image]; DhGPUImageQingXinFilter *filter = [[DhGPUImageQingXinFilter alloc] init]; [self addFilter:filter]; [imageSource addTarget:filter atTextureLocation:1]; [imageSource processImage]; imageSource2 = [[GPUImagePicture alloc] initWithImage:image2]; DhGPUImageQingXinFilter *filter2 = [[DhGPUImageQingXinFilter alloc] init]; [filter addTarget:filter2]; [imageSource2 addTarget:filter2]; [imageSource2 processImage]; [self addFilter:filter2]; self.initialFilters = [NSArray arrayWithObjects:filter, nil]; self.terminalFilter = filter; return self; } - (void)dealloc { #if !OS_OBJECT_USE_OBJC if (imageCaptureSemaphore != NULL) { dispatch_release(imageCaptureSemaphore); } #endif } @end