iOS濾鏡功能


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

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM