GPUImage詳細解析(四)模糊圖片處理

回顧

解析(一)
解析(二)
解析(三)
這次介紹的GPUImageContextGPUImageFramebufferCacheGPUImagePicture

GPUImageContext

GPUImageContext是GPUImage對OpenGL ES上下文的封裝,添加了GPUImage相關的上下文,比如說Program的使用緩存,處理隊列,CV紋理緩存等。

1、屬性介紹

contextQueue 統一處理隊列
currentShaderProgram 正在使用的program
context OpenGL ES的上下文
coreVideoTextureCache CV紋理緩存
framebufferCache GPUImageBuffer緩存
shaderProgramCache Program的緩存
shaderProgramUsageHistory Program的使用歷史

2、方法介紹

  • useAsCurrentContext() 在useAsCurrentContext設置當前上下文的時候,會先判斷上下文是否是當前context,不是再設置(為了避免上下文切換的性能消耗,即使設置的上下文是同一個上下文也會消耗性能)

  • sizeThatFitsWithinATextureForSize() 會調整紋理大小,如果超過最大的紋理,會調整為不超過最大的紋理寬高。

  • (GLProgram*)programForVertexShaderString:fragmentShaderString:;
    shaderProgramCache 是program的緩存,由頂點shader和片元shader字符串拼接起來做key。

  • - (void)useSharegroup:(EAGLSharegroup *)sharegroup;
    EAGLSharegroup類管理一個或者多個EAGLContext的OpenGLES資源;這個是一個封閉的類,沒有開發者API。負責管理紋理緩存、頂點緩存、幀緩存、顏色緩存。(textures, buffers, framebuffers, and render buffers)

  • - (EAGLContext *)context;返回OpenGL ES2.0的上下文,同時設置glDisable(GL_DEPTH_TEST);,圖像處理管道默認不允許使用深度緩存。

GPUImageFramebufferCache

GPUImageFramebufferCache是GPUImageFrameBuffer的管理類

1、屬性介紹

CacheframebufferCache 緩存字典
framebufferTypeCounts 緩存數量字典
activeImageCaptureList 正在讀取Image數據的GPUImageFrameBuffer列表
framebufferCacheQueue 緩存隊列

2、方法介紹

  • - (NSString *)hashForSize: textureOptions:onlyTexture:;
    根據size、textureOptions和onlyTexture,創建緩存字符串。
    緩存字符串+當前緩存數量形成framebufferCache緩存的key。
    如果找不到framebufferCache對應的數量,會創建新的緩存。

  • - (void)returnFramebufferToCache:;回收緩存。根據size、textureOptions和onlyTexture,創建緩存字符串,緩存字符串+當前緩存數量形成framebufferCache緩存的key。(之所以會加上數量,是因為緩存字符串不唯一)

  • - (void)addFramebufferToActiveImageCaptureList:;
    - (void)removeFramebufferFromActiveImageCaptureList:
    這兩個方法主要用于,當newCGImageFromFramebufferContents()讀取幀緩存圖像數據時,保持GPUImageFramebuffer的引用。并且讀取完數據后,在dataProviderUnlockCallback()方法釋放。

GPUImagePicture

GPUImagePicture是PGUImage的圖像處理類,繼承GPUImageOutput,一般作為響應鏈的源頭。

1、屬性介紹

pixelSizeOfImage 圖像的像素大小。
hasProcessedImage 圖像是否已處理。
imageUpdateSemaphore 圖像處理的GCD信號量。

2、方法介紹

  • - (id)initWithCGImage:smoothlyScaleOutput: 用源圖像newImageSource和是否采用mipmaps來初始化GPUImagePicture。
    如果圖像大小超過OpenGL ES最大紋理寬高,或者使用mipmaps,或者圖像數據是浮點型、顏色空間不對等都會采用CoreGraphics重新繪制圖像。
    然后通過glTexImage2D把圖像數據發送給GPU,最后釋放掉CPU的圖像數據。

  • - (BOOL)processImageWithCompletionHandler:; 通知targets處理圖像,并在完成后調用complete代碼塊。在處理開始時,會標記hasProcessedImage為YES,并調用dispatch_semaphore_wait(),確定上次處理已經完成,否則取消這次處理。

  • - (void)addTarget: atTextureLocation:;添加target到響應鏈。如果hasProcessedImage為YES,表示圖像已經處理完畢,直接設置targets的InputSize,并調用newFrameReadyAtTime()通知target。

DEMO

用GPUImagePicture處理源圖像,用GPUImageTiltShiftFilter處理模糊效果,用GPUImageView顯示。

效果展示

核心代碼

將GPUImageView設置為self.view,根據face.png,設置GPUImagePicture,然后添加GPUImageTiltShiftFilter到響應鏈,再把GPUImageView作為響應鏈的終點,最后調用processImage,開始處理圖像。

    GPUImageView *primaryView = [[GPUImageView alloc] initWithFrame:self.view.frame];
    self.view = primaryView;
    UIImage *inputImage = [UIImage imageNamed:@"face.png"];
    _sourcePicture = [[GPUImagePicture alloc] initWithImage:inputImage];
    _sepiaFilter = [[GPUImageTiltShiftFilter alloc] init];
    _sepiaFilter.blurRadiusInPixels = 40.0;
    [_sepiaFilter forceProcessingAtSize:primaryView.sizeInPixels];
    [_sourcePicture addTarget:_sepiaFilter];
    [_sepiaFilter addTarget:primaryView];
    [_sourcePicture processImage];

總結

最近因為直播用戶增長太快,忙著優化原來的邏輯,研讀源代碼的時間變少。
同時為了寫這篇文章,查了一些關于圖像資料,末尾附上。
下一篇文章可能會介紹今年大火的直播APP的一種速成方案,也可能會是GPUImageMovie的介紹。
喜歡的點一下關注,不迷路。

MIPMAP

Mipmap紋理技術是目前解決紋理分辨率與視點距離關系的最有效途徑,它會先將圖片壓縮成很多逐漸縮小的圖片,例如一張6464的圖片,會產生6464,3232,1616,88,44,22,11的7張圖片,當屏幕上需要繪制像素點為2020 時,程序只是利用 3232 和 1616 這兩張圖片來計算出即將顯示為 2020 大小的一個圖片,這比單獨利用 32*32 的那張原始片計算出來的圖片效果要好得多,速度也更快.

圖像數據格式

kCGImageAlphaLast:alpha 分量存儲在每個像素中的低位,如RGBA。
kCGImageAlphaFirst:alpha 分量存儲在每個像素中的高位,如ARGB。
kCGImageAlphaPremultipliedLast:alpha 分量存儲在每個像素中的低位,同時顏色分量已經乘以了 alpha 值。
kCGImageAlphaPremultipliedFirst:alpha 分量存儲在每個像素中的高位,同時顏色分量已經乘以了 alpha 值。
kCGImageAlphaNoneSkipLast:沒有 alpha 分量。如果像素的總大小大于顏色空間中顏色分量數目所需要的空間,則低位將被忽略。
kCGImageAlphaNoneSkipFirst:沒有 alpha 分量。如果像素的總大小大于顏色空間中顏色分量數目所需要的空間,則高位將被忽略。

圖像顏色空間

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容