直播預(yù)覽層添加濾鏡效果(CIFilter使用場(chǎng)景)

直播預(yù)覽層添加濾鏡效果

  • 原理,在顯示之前,提前對(duì)圖片進(jìn)行濾鏡處理,把處理后的圖片展示出來(lái)就好了.

  • CIFiter(濾鏡類):給圖片添加特殊效果(模糊,高亮等等).

  • CIFiter濾鏡分類(一個(gè)濾鏡可能屬于多個(gè)分類)

    • kCICategoryDistortionEffect 扭曲效果,比如bump、旋轉(zhuǎn)、hole
    • kCICategoryGeometryAdjustment 幾何開(kāi)著調(diào)整,比如仿射變換、平切、透視轉(zhuǎn)換
    • kCICategoryCompositeOperation 合并,比如源覆蓋(source over)、最小化、源在頂(source atop)、色彩混合模式
    • kCICategoryHalftoneEffect Halftone效果,比如screen、line screen、hatched
    • kCICategoryColorAdjustment 色彩調(diào)整,比如伽馬調(diào)整、白點(diǎn)調(diào)整、曝光
    • kCICategoryColorEffect 色彩效果,比如色調(diào)調(diào)整、posterize
    • kCICategoryTransition 圖像間轉(zhuǎn)換,比如dissolve、disintegrate with mask、swipe
    • kCICategoryTileEffect 瓦片效果,比如parallelogram、triangle
    • kCICategoryGenerator 圖像生成器,比如stripes、constant color、checkerboard
    • kCICategoryGradient 漸變,比如軸向漸變、仿射漸變、高斯?jié)u變
    • kCICategoryStylize 風(fēng)格化,比如像素化、水晶化
    • kCICategorySharpen 銳化、發(fā)光
    • kCICategoryBlur 模糊,比如高斯模糊、焦點(diǎn)模糊、運(yùn)動(dòng)模糊
    • kCICategoryStillImage 能用于靜態(tài)圖像
    • kCICategoryVideo 能用于視頻
    • kCICategoryInterlaced 能用于交錯(cuò)圖像
    • kCICategoryNonSquarePixels 能用于非矩形像素
    • kCICategoryHighDynamicRange 能用于HDR
    • kCICategoryBuiltIn 獲取所有濾鏡
  • 常用圖片處理濾鏡:

    
    // 懷舊 --> CIPhotoEffectInstant                         單色 --> CIPhotoEffectMono
    // 黑白 --> CIPhotoEffectNoir                            褪色 --> CIPhotoEffectFade
    // 色調(diào) --> CIPhotoEffectTonal                           沖印 --> CIPhotoEffectProcess
    // 歲月 --> CIPhotoEffectTransfer                        鉻黃 --> CIPhotoEffectChrome
    
    
  • 自動(dòng)處理濾鏡,通過(guò)CIImage獲取,CIImage會(huì)自動(dòng)對(duì)圖片進(jìn)行濾鏡處理

    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
        
    // 轉(zhuǎn)換為CIImage
    CIImage *ciImage = [CIImage imageWithCVImageBuffer:imageBuffer];
        
        
    NSArray *fiters = [ciImage autoAdjustmentFilters];
        
    NSLog(@"%@",fiters);
  • 常有的自動(dòng)濾鏡

        CIRedEyeCorrection:修復(fù)因相機(jī)的閃光燈導(dǎo)致的各種紅眼
        CIFaceBalance:調(diào)整膚色
        CIVibrance:在不影響膚色的情況下,改善圖像的飽和度
        CIToneCurve:改善圖像的對(duì)比度
        CIHighlightShadowAdjust:改善陰影細(xì)節(jié)      
    
  • 濾鏡對(duì)象創(chuàng)建(也可以使用coreImage自動(dòng)處理濾鏡,就不需要自己創(chuàng)建)

  • 濾鏡屬性可以通過(guò)inputKeys屬性獲取

  • 濾鏡工作原理,給濾鏡傳入一個(gè)圖片,濾鏡有個(gè)方法,可以獲取處理完成的圖片outputImage.

        CIFilter *fiter = [CIFilter filterWithName:@"CIPhotoEffectInstant"];
        
        [fiter setValue:ciImage forKey:@"inputImage"];
        
        ciImage = fiter.outputImage;

直播預(yù)覽層添加濾鏡效果步驟

  • 取出捕獲到的幀(CMSampleBufferRef) -> 獲取幀里面圖片信息(CVImageBufferRef) -> CIFiter濾鏡處理 ->轉(zhuǎn)換成UIImage -> 設(shè)置為UIImageView的image就能實(shí)時(shí)顯示捕獲的畫(huà)面
if (_videoConnection == connection) {
        // 獲取圖片信息
        CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
        
        // 轉(zhuǎn)換為CIImage
        CIImage *ciImage = [CIImage imageWithCVImageBuffer:imageBuffer];
        
        // 創(chuàng)建濾鏡
        CIFilter *fiter = [CIFilter filterWithName:@"CIFaceBalance"];
        
        [fiter setValue:ciImage forKey:@"inputImage"];
        [fiter setValue:@100 forKey:@"inputStrength"];
        ciImage = fiter.outputImage;
        
        // 轉(zhuǎn)換UIImage
        UIImage *image = [UIImage imageWithCIImage:ciImage];
        
        dispatch_sync(dispatch_get_main_queue(), ^{
            
            self.imageView.image = image;
            
        });
    }

通過(guò)GPU渲染圖片顯示

  • 只有OpenGL才能操控GPU,需要用到OpenGL才行
  • CIContext:通過(guò)這個(gè)上下文的方法渲染圖片(createCGImage)
  • CIContext:通過(guò)OpenGL的上下文創(chuàng)建,就能用GPU渲染圖片,處理圖片效率高.(contextWithEAGLContext)
  // 獲取圖片信息
            CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
            
            // 轉(zhuǎn)換為CIImage
            CIImage *ciImage = [CIImage imageWithCVImageBuffer:imageBuffer];
            
            // 創(chuàng)建濾鏡
            CIFilter *fiter = [CIFilter filterWithName:@"CIPhotoEffectInstant"];
            
            [fiter setValue:ciImage forKey:@"inputImage"];
            
            ciImage = fiter.outputImage;
            
            EAGLContext *openglCtx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
            CIContext *ctx = [CIContext contextWithEAGLContext:openglCtx];
            
            CGImageRef imgRef = [ctx createCGImage:ciImage fromRect:ciImage.extent];
            
            UIImage *image = [UIImage imageWithCGImage:imgRef];
        
            // 用完了及時(shí)清空,否則內(nèi)存溢出,造成程序崩潰.使用C語(yǔ)言的時(shí)候,需要特別注意內(nèi)存管理.
            CGImageRelease(imgRef);
        
            // 轉(zhuǎn)換UIImage
            
            dispatch_sync(dispatch_get_main_queue(), ^{
                
                self.imageView.image = image;
                
                
            });
  • 注意點(diǎn):有個(gè)地方需要自己管理內(nèi)存,否則程序會(huì)閃退,報(bào)下列錯(cuò)誤
內(nèi)存溢出bug.png
CGImageRef imgRef = [ctx createCGImage:ciImage fromRect:ciImage.extent];
            
UIImage *image = [UIImage imageWithCGImage:imgRef];
        
// 用完了及時(shí)清空,否則內(nèi)存溢出,造成程序崩潰.使用C語(yǔ)言的時(shí)候,需要特別注意內(nèi)存管理.
CGImageRelease(imgRef);
  • 注意點(diǎn):會(huì)報(bào)壞內(nèi)存訪問(wèn),原因有些對(duì)象銷(xiāo)毀了,沒(méi)有及時(shí)清空,再次用到就壞內(nèi)存訪問(wèn)
  • 測(cè)試:不需要添加濾鏡效果,容易測(cè)試出來(lái),報(bào)下列錯(cuò)誤
壞內(nèi)存訪問(wèn).png
  • 解決:把一個(gè)周期的代碼,放入一個(gè)自動(dòng)釋放池里管理,下一個(gè)運(yùn)行循環(huán),會(huì)自動(dòng)清空已經(jīng)銷(xiāo)毀的對(duì)象。
  • 自動(dòng)釋放池:可以用來(lái)管理一段代碼中對(duì)象的生命周期。
 @autoreleasepool {
            // 獲取圖片信息
            CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
            
            // 轉(zhuǎn)換為CIImage
            CIImage *ciImage = [CIImage imageWithCVImageBuffer:imageBuffer];
            
            // 創(chuàng)建濾鏡
            CIFilter *fiter = [CIFilter filterWithName:@"CIPhotoEffectInstant"];
            
            [fiter setValue:ciImage forKey:@"inputImage"];
            
            ciImage = fiter.outputImage;
        
            EAGLContext *openglCtx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
            CIContext *ctx = [CIContext contextWithEAGLContext:openglCtx];
            
            CGImageRef imgRef = [ctx createCGImage:ciImage fromRect:ciImage.extent];
            
            UIImage *image = [UIImage imageWithCGImage:imgRef];
        
            // 用完了及時(shí)清空,否則內(nèi)存溢出,造成程序崩潰.使用C語(yǔ)言的時(shí)候,需要特別注意內(nèi)存管理.
            CGImageRelease(imgRef);
        
            // 轉(zhuǎn)換UIImage
            
            dispatch_sync(dispatch_get_main_queue(), ^{
                
                self.imageView.image = image;
                
            });

        }
        
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 許多UIView的子類,如一個(gè)UIButton或一個(gè)UILabel,它們知道怎么繪制自己。遲早,你也將想要做一些自...
    shenzhenboy閱讀 1,759評(píng)論 2 8
  • --繪圖與濾鏡全面解析 概述 在iOS中可以很容易的開(kāi)發(fā)出絢麗的界面效果,一方面得益于成功系統(tǒng)的設(shè)計(jì),另一方面得益...
    韓七夏閱讀 2,981評(píng)論 2 10
  • 網(wǎng)頁(yè)布局(layout)是 CSS 的一個(gè)重點(diǎn)應(yīng)用。 布局的傳統(tǒng)解決方案,基于盒狀模型,依賴 display屬性 ...
    流沙麒麟客閱讀 819評(píng)論 0 0
  • 1、二次元產(chǎn)業(yè)細(xì)分 動(dòng)畫(huà)(內(nèi)容):奧飛動(dòng)漫、卡酷動(dòng)畫(huà)、原創(chuàng)動(dòng)力 漫畫(huà)(內(nèi)容):有妖氣、漫客網(wǎng)、騰訊原創(chuàng)動(dòng)漫 版權(quán)代...
    jlnbda3488375閱讀 415評(píng)論 0 2
  • 娃今年10歲了, 他活潑好動(dòng)的個(gè)性和天馬行空的思維,在學(xué)校給老師平添了不少麻煩,老師時(shí)??嗫谄判牡匕押⒆拥囊恍┣闆r...
    冉燈閱讀 526評(píng)論 3 0

友情鏈接更多精彩內(nèi)容