一、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
