iOS開發——GPUImage源碼解析

1、基本概念算法

  • GPUImage:一個開源的、基於openGL的圖片或視頻的處理框架,其自己內置了多達120多種常見的濾鏡效果,而且支持照相機和攝像機的實時濾鏡,而且可以自定義圖像濾鏡。同時也很方便在原有基礎上加入本身的濾鏡Filter,全部濾鏡是基於opengl shader(着色器)實現的,因此濾鏡效果圖像處理是在GPU上實現的,處理效率比較高,在iPhone6及其以上手機,能夠作到實時流暢的效果。
  • GPU:(圖形處理單元)手機或者電腦用於圖像處理和渲染的硬件。
  • GPU工做原理:CPU指定顯示器工做,顯示控制器根據CPU的控制到指定的地方去取數據和指令,目前的數據通常是從顯存裏取,若是顯存裏存不下,則從內存裏取,內存也放不下,則從硬盤裏取。
  • 濾鏡處理的原理:就是把靜態圖片或者視頻的每一幀進行圖形變化後在顯示到屏幕上,其本質就是像素點的座標和顏色的變化。  
  • OpenGL ES:開源嵌入式系統圖形的處理框架,一套圖形與硬件接口,創造了軟件與圖形加速間靈活強大的底層交互接口。用於把處理好的圖片顯示到屏幕上。

  OpenGL ES程序處理圖片步驟:
  一、初始化OpenGL ES環境,編譯、連接頂點着色器和片元着色器;
  二、緩存頂點、紋理座標數據,傳送圖像數據到GPU;
  三、繪製圖元到特定的幀緩存;
  四、在幀緩存取出繪製的圖像。chrome

 

2、GPUImage處理畫面的流程緩存

  GPUImage是採用鏈式方法來處理畫面,經過addTarget方法添加對象到鏈中,處理完一個target,就會把上一個環節處理好的圖像數據傳遞到下一個target處理,稱爲GPUImage處理鏈。中間環節的target, 通常是各類filter, 是GPUImageFilter或者是子類。最終環節的target, GPUImageView:用於顯示到屏幕上, 或者GPUImageMovieWriter:寫成視頻文件。架構

  GPUImage的四大輸入基礎類,均可以做爲響應鏈的起點,這些基礎類會把圖像做爲紋理傳給OpenGL ES處理,而後把紋理傳遞給響應鏈的下一個target對象。框架

  

 

 

  GPUImage的處理主要分爲三個環節:ssh

  source(視頻,圖片源)->filter(濾鏡)->final target(處理後的視頻、圖片)ide

  一、source函數

  GPUImaged的Source:都繼承GPUImageOutput的子類,做爲GPUImage的數據源,就比如外界的光線,做爲眼睛的輸出源。動畫

  • GPUImageVideoCamera 攝像頭-用於實時拍攝視頻
  • GPUImageStillCamera 攝像頭-用於實時拍攝照片
  • GPUImagePicture 用於處理已經拍攝好的圖片
  • GPUImageMovie 用於處理已經拍攝好的視頻

  二、filterspa

  GPUImageFilter:就是用來接收源圖像,經過自定義的頂點,片元着色器來渲染新的圖像,並在繪製完成後通知響應鏈的下一個對象。

  GPUImageFramebuffer:就是用來管理紋理緩存的格式與讀寫幀緩存的buffer。

  GPUImage的filter:GPUImageFilter類或者子類,這個類繼承自GPUImageOutput,遵循GPUImageInput協議,既能夠流進數據,又能夠流出

  GPUImage的final target: GPUImageView,GPUImageMovieWriter最終輸入目標,顯示圖片或者視頻。

 

3、GPUImage工做原理

  • GPUImage最關鍵在於GPUImageFramebuffer這個類,這個類會保存當前處理好的圖片信息。
  • GPUImage是經過一個鏈條處理圖片,每一個鏈條經過target鏈接,每一個target處理完圖片後,會生成一個GPUImageFramebuffer對象,而且把圖片信息保存到GPUImageFramebuffer。
  • 這樣好比targetA處理好,要處理targetB,就會先取出targetA的圖片,而後targetB在targetA的圖片基礎上在進行處理.

 

  GPUImage基本架構是chain式結構,主要由一個GPUImageOutput interface和一個GPUImageInput protocol串聯起來,GPUImageOutput輸出Texture,GPUImageInput輸入Texture,整個鏈式圖像數據傳遞由Texture擔當。camera,stillimage等圖像、視頻sources繼承自GPUImageOutput,濾鏡Filters繼承自GPUImageOutput並實現GPUImageInput,View,FileWriter等Outputs實現GPUImageInput,大體結構以下圖:

   先來看GPUImageOutput,裏面有兩個很重要的變量:GPUImageFramebuffer指針類型的outputFramebuffer和NSMutableArray指針類型的targets,四個接口重要接口:notifyTargetAboutNewOutputTexture、setInputFramebufferForTartget、addTarget和removeTarget,下面分別來看看:

  • outputFramebuffer變量主要是負責管理GPUImageOutput(包括Sources和Filters)產生的Texture。texture爲其表明輸出的Texture的index。missingFramebuffer,決定是否生成RenderBuffer,由初始化函數initWIthSize參數是onlyGenerateTexture決定,若是是YES,內部只產生Texture,好比假設源GUPImageVideocamera採集到的視頻數據是RGB數據,直接用glTextImage2D更新紋理,若是爲NO,則生成Texture的同時生成Framebuffer,Texture更新方式經過RendFramebuffer來實現,若是GUPImageVideocamera採集到的數據爲YUV時,經過opengl實現YUV到到RGB的轉化,用Texture綁定到Framebuffer的方式更新Texture,全部的Filters都是採用Framebuffer更新方式,由於須要用opengl進行圖像處理。pixelBuffer用一個CVPixelBuffer類型變量,主要用來實現GPU和CPU之間的數據高效共享,這樣pixelBuffer數據和texture紋理數據同步更新,便於在CPU和GPU端同時高效訪問。
  • targets變量主要是負責管理GPUImageOutput下游GPUImageInput,也就是連接到該GPUImageOutput上的GPUImageInput集合,經過接口addTarget和RemoveTarget來進行管理下游GPUImageInput。
  • setInputFramebufferForTartget就是將GPUImageOutput生成的outputFramebuffer設置給下游GPUImageInput target,這樣下游GPUImageInput就是在上游GPUImageOutput處理後texture上作處理。
  • notifyTargetAboutNewOutputTexture該函數就是在上游GPUImageOutput處理完後,對targets每個下游GPUImageInput循環調用setInputFramebufferForTartget,完成texture傳遞。

  經過上述變量和接口,基本上能夠懂得GPUImageOutput作了什麼工做,基本上就是經過opengl對圖像作處理,所處理的結果存在了outputFramebuffer管理的texture紋理上,並在處理完後,經過notifyTargetAboutNewOutputTexture接口將texture結果傳遞給下游GPUImageInput。

  如今咱們來看看GPUImageInput協議,主要有setInputFramebuffer和newFrameReadyAtTime兩個接口。

  • setInputFramebuffer正是GPUImageOutput執行setInputFramebufferForTartget調用的,將處理後的texture傳遞下來。
  • newFrameReadyAtTime緊着跟着setInputFramebuffer被調用,驅動GPUImageInput進行處理。

  這樣sources繼承GPUImageOutput,filters繼承GPUImageOutput和實現GPUImageInput,outputs實現GPUImageInput,一條圖像處理數據鏈就造成了。 

  根據提供的默認值,加上對濾鏡的命名的理解,粗略簡單地對GPUImage.h裏引用的各個濾鏡進行簡要說明。這樣方便之後找到想要的濾鏡效果。其中可能有理解錯誤,或者表達不許確的地方還請你們斧正。其中有些效果須要使用攝像頭纔可能有比較理想的效果。

 

4、GPUImage源文件解讀

#pragma mark - 調整顏色 Handle Color

#import "GPUImageBrightnessFilter.h"                //亮度
#import "GPUImageExposureFilter.h"                  //曝光
#import "GPUImageContrastFilter.h"                  //對比度
#import "GPUImageSaturationFilter.h"                //飽和度
#import "GPUImageGammaFilter.h"                     //伽馬線
#import "GPUImageColorInvertFilter.h"               //反色
#import "GPUImageSepiaFilter.h"                     //褐色(懷舊)
#import "GPUImageLevelsFilter.h"                    //色階
#import "GPUImageGrayscaleFilter.h"                 //灰度
#import "GPUImageHistogramFilter.h"                 //色彩直方圖,顯示在圖片上
#import "GPUImageHistogramGenerator.h"              //色彩直方圖
#import "GPUImageRGBFilter.h"                       //RGB
#import "GPUImageToneCurveFilter.h"                 //色調曲線
#import "GPUImageMonochromeFilter.h"                //單色
#import "GPUImageOpacityFilter.h"                   //不透明度
#import "GPUImageHighlightShadowFilter.h"           //提亮陰影
#import "GPUImageFalseColorFilter.h"                //色彩替換(替換亮部和暗部色彩)
#import "GPUImageHueFilter.h"                       //色度
#import "GPUImageChromaKeyFilter.h"                 //色度鍵
#import "GPUImageWhiteBalanceFilter.h"              //白平橫
#import "GPUImageAverageColor.h"                    //像素平均色值
#import "GPUImageSolidColorGenerator.h"             //純色
#import "GPUImageLuminosity.h"                      //亮度平均
#import "GPUImageAverageLuminanceThresholdFilter.h" //像素色值亮度平均,圖像黑白(有相似漫畫效果)

#import "GPUImageLookupFilter.h"                    //lookup 色彩調整
#import "GPUImageAmatorkaFilter.h"                  //Amatorka lookup
#import "GPUImageMissEtikateFilter.h"               //MissEtikate lookup
#import "GPUImageSoftEleganceFilter.h"              //SoftElegance lookup

#pragma mark - 圖像處理 Handle Image

#import "GPUImageCrosshairGenerator.h"              //十字
#import "GPUImageLineGenerator.h"                   //線條

#import "GPUImageTransformFilter.h"                 //形狀變化
#import "GPUImageCropFilter.h"                      //剪裁
#import "GPUImageSharpenFilter.h"                   //銳化
#import "GPUImageUnsharpMaskFilter.h"               //反遮罩銳化

#import "GPUImageFastBlurFilter.h"                  //模糊
#import "GPUImageGaussianBlurFilter.h"              //高斯模糊
#import "GPUImageGaussianSelectiveBlurFilter.h"     //高斯模糊,選擇部分清晰
#import "GPUImageBoxBlurFilter.h"                   //盒狀模糊
#import "GPUImageTiltShiftFilter.h"                 //條紋模糊,中間清晰,上下兩端模糊
#import "GPUImageMedianFilter.h"                    //中間值,有種稍微模糊邊緣的效果
#import "GPUImageBilateralFilter.h"                 //雙邊模糊
#import "GPUImageErosionFilter.h"                   //侵蝕邊緣模糊,變黑白
#import "GPUImageRGBErosionFilter.h"                //RGB侵蝕邊緣模糊,有色彩
#import "GPUImageDilationFilter.h"                  //擴展邊緣模糊,變黑白
#import "GPUImageRGBDilationFilter.h"               //RGB擴展邊緣模糊,有色彩
#import "GPUImageOpeningFilter.h"                   //黑白色調模糊
#import "GPUImageRGBOpeningFilter.h"                //彩色模糊
#import "GPUImageClosingFilter.h"                   //黑白色調模糊,暗色會被提亮
#import "GPUImageRGBClosingFilter.h"                //彩色模糊,暗色會被提亮
#import "GPUImageLanczosResamplingFilter.h"         //Lanczos重取樣,模糊效果
#import "GPUImageNonMaximumSuppressionFilter.h"     //非最大抑制,只顯示亮度最高的像素,其餘爲黑
#import "GPUImageThresholdedNonMaximumSuppressionFilter.h" //與上相比,像素丟失更多

#import "GPUImageSobelEdgeDetectionFilter.h"        //Sobel邊緣檢測算法(白邊,黑內容,有點漫畫的反色效果)
#import "GPUImageCannyEdgeDetectionFilter.h"        //Canny邊緣檢測算法(比上更強烈的黑白對比度)
#import "GPUImageThresholdEdgeDetectionFilter.h"    //閾值邊緣檢測(效果與上差異不大)
#import "GPUImagePrewittEdgeDetectionFilter.h"      //普瑞維特(Prewitt)邊緣檢測(效果與Sobel差很少,貌似更平滑)
#import "GPUImageXYDerivativeFilter.h"              //XYDerivative邊緣檢測,畫面以藍色爲主,綠色爲邊緣,帶彩色
#import "GPUImageHarrisCornerDetectionFilter.h"     //Harris角點檢測,會有綠色小十字顯示在圖片角點處
#import "GPUImageNobleCornerDetectionFilter.h"      //Noble角點檢測,檢測點更多
#import "GPUImageShiTomasiFeatureDetectionFilter.h" //ShiTomasi角點檢測,與上差異不大
#import "GPUImageMotionDetector.h"                  //動做檢測
#import "GPUImageHoughTransformLineDetector.h"      //線條檢測
#import "GPUImageParallelCoordinateLineTransformFilter.h" //平行線檢測

#import "GPUImageLocalBinaryPatternFilter.h"        //圖像黑白化,並有大量噪點

#import "GPUImageLowPassFilter.h"                   //用於圖像加亮
#import "GPUImageHighPassFilter.h"                  //圖像低於某值時顯示爲黑


#pragma mark - 視覺效果 Visual Effect

#import "GPUImageSketchFilter.h"                    //素描
#import "GPUImageThresholdSketchFilter.h"           //閥值素描,造成有噪點的素描
#import "GPUImageToonFilter.h"                      //卡通效果(黑色粗線描邊)
#import "GPUImageSmoothToonFilter.h"                //相比上面的效果更細膩,上面是粗曠的畫風
#import "GPUImageKuwaharaFilter.h"                  //桑原(Kuwahara)濾波,水粉畫的模糊效果;處理時間比較長,慎用

#import "GPUImageMosaicFilter.h"                    //黑白馬賽克
#import "GPUImagePixellateFilter.h"                 //像素化
#import "GPUImagePolarPixellateFilter.h"            //同心圓像素化
#import "GPUImageCrosshatchFilter.h"                //交叉線陰影,造成黑白網狀畫面
#import "GPUImageColorPackingFilter.h"              //色彩丟失,模糊(相似監控攝像效果)

#import "GPUImageVignetteFilter.h"                  //暈影,造成黑色圓形邊緣,突出中間圖像的效果
#import "GPUImageSwirlFilter.h"                     //漩渦,中間造成捲曲的畫面
#import "GPUImageBulgeDistortionFilter.h"           //凸起失真,魚眼效果
#import "GPUImagePinchDistortionFilter.h"           //收縮失真,凹面鏡
#import "GPUImageStretchDistortionFilter.h"         //伸展失真,哈哈鏡
#import "GPUImageGlassSphereFilter.h"               //水晶球效果
#import "GPUImageSphereRefractionFilter.h"          //球形折射,圖形倒立
    
#import "GPUImagePosterizeFilter.h"                 //色調分離,造成噪點效果
#import "GPUImageCGAColorspaceFilter.h"             //CGA色彩濾鏡,造成黑、淺藍、紫色塊的畫面
#import "GPUImagePerlinNoiseFilter.h"               //柏林噪點,花邊噪點
#import "GPUImage3x3ConvolutionFilter.h"            //3x3卷積,高亮大色塊變黑,加亮邊緣、線條等
#import "GPUImageEmbossFilter.h"                    //浮雕效果,帶有點3d的感受
#import "GPUImagePolkaDotFilter.h"                  //像素圓點花樣
#import "GPUImageHalftoneFilter.h"                  //點染,圖像黑白化,由黑點構成原圖的大體圖形


#pragma mark - 混合模式 Blend

#import "GPUImageMultiplyBlendFilter.h"             //一般用於建立陰影和深度效果
#import "GPUImageNormalBlendFilter.h"               //正常
#import "GPUImageAlphaBlendFilter.h"                //透明混合,一般用於在背景上應用前景的透明度
#import "GPUImageDissolveBlendFilter.h"             //溶解
#import "GPUImageOverlayBlendFilter.h"              //疊加,一般用於建立陰影效果
#import "GPUImageDarkenBlendFilter.h"               //加深混合,一般用於重疊類型
#import "GPUImageLightenBlendFilter.h"              //減淡混合,一般用於重疊類型
#import "GPUImageSourceOverBlendFilter.h"           //源混合
#import "GPUImageColorBurnBlendFilter.h"            //色彩加深混合
#import "GPUImageColorDodgeBlendFilter.h"           //色彩減淡混合
#import "GPUImageScreenBlendFilter.h"               //屏幕包裹,一般用於建立亮點和鏡頭眩光
#import "GPUImageExclusionBlendFilter.h"            //排除混合
#import "GPUImageDifferenceBlendFilter.h"           //差別混合,一般用於建立更多變更的顏色
#import "GPUImageSubtractBlendFilter.h"             //差值混合,一般用於建立兩個圖像之間的動畫變暗模糊效果
#import "GPUImageHardLightBlendFilter.h"            //強光混合,一般用於建立陰影效果
#import "GPUImageSoftLightBlendFilter.h"            //柔光混合
#import "GPUImageChromaKeyBlendFilter.h"            //色度鍵混合
#import "GPUImageMaskFilter.h"                      //遮罩混合
#import "GPUImageHazeFilter.h"                      //朦朧加暗
#import "GPUImageLuminanceThresholdFilter.h"        //亮度閾
#import "GPUImageAdaptiveThresholdFilter.h"         //自適應閾值
#import "GPUImageAddBlendFilter.h"                  //一般用於建立兩個圖像之間的動畫變亮模糊效果
#import "GPUImageDivideBlendFilter.h"               //一般用於建立兩個圖像之間的動畫變暗模糊效果
相關文章
相關標籤/搜索