Core Image:iOS圖像處理技術追蹤

簡介

Core Image是蘋果官方提供的圖像處理框架,經過豐富的built-in(內置)或自定義Filter(過濾器)高效處理靜態圖片、動態圖片或視頻。開發者還能夠經過構造Filter鏈或自定義Core Image Kernel來實現更豐富的效果。node

在WWDC20中,蘋果官方針對Core Image技術在如下三方面作了優化:Core Image對視頻/動圖的支持、基於Metal構建Core Image (CI) Kernel以及Core Image的Debug支持。這三方面會在下文逐一提到,文末筆者也會淺談Core Image在手淘圖片庫中的應用可能以及對Core Image技術的展望。git

( WWDC 2020精彩內容思否專欄:https://segmentfault.com/blog...  github

本篇內容來自於阿里巴巴淘系技術部,無線開發工程師越伯。
更多精彩內容可關注【淘系技術】公衆號。)segmentfault

優化Core Image對視頻/動圖的支持

1. 建立CIContext

建立CIContext時,須要遵循一個view一個context的原則。因爲視頻的每一幀都會發生變化,將CIContext的cacheIntermediates屬性設置爲false能夠大大減小內存消耗。緩存

若是在使用Core Image時將同時運用Metal(做爲輸入或輸出),經過設置MTLCommandQueue屬性建立CIContext將會是較好選擇。在不使用MTLCommandQueue的狀況下,每個Metal或CoreImage執行的任務都在不一樣隊列中並以wait命令分隔開,致使任務執行效率低。經過設置MTLCommandQueue建立的CIContext和相應的Metal任務在同一隊列中,能提升app的運行效率。網絡

image.png

圖1、不使用MTLCommandQueue的工做流程app

image.png

圖2、使用MTLCommandQueue的工做流程框架

2. 編寫Core Image Kernel(在Metal中實現)

爲了將效果處理得更豐富,經過Metal來實現自定義CI Kernel是個高效的選擇。蘋果官方提供了的許多方便部署的內置工具(都經過Metal實現),如內置CI濾鏡。經過Metal實現自定義CI Kernel,不只app的runtime編譯時間將會大大減小(這段工做會移至app構建完成後進行),開發者還能得到高性能語言特性(如gather-reads、group-writes、半精度浮點數)、高效開發體驗(如縮進檢查、縮進高光)等功能。ide

3. 選擇合適的View類

若是要對視頻/動圖應用特效,靜態內容View如UIImageView或NSImageView應當被避免。AVPlayerView和MetalKit View(MTKView)是個兩個不錯的選擇。前者爲簡單選擇,後者爲進階選擇。函數

使用AVPlayerView時,須要建立AVMutableVideoComposition對象,CI濾鏡在block中執行圖像處理任務。在進行斷點debug時,經過點擊CIImage對象地址右側的眼睛圖示能夠瀏覽CI濾鏡處理流程的詳細信息。官方提供的案例中,Core Image還將10位的HDR視頻幀數據自動從HLG轉化成了Core Image working space。

image.png

圖3、CI Image斷點測試中展示的處理流程

使用MTKView時,開發者須要以frame和device做爲參數重載init方法。VIew對應的CIContext也將在init函數中被建立。若是咱們在macOS中開發支持HDR的view,color-Pixel-Format屬性須要被設定爲rgba16Float,wants-Extended-Dynamic-Range-Content屬性須要被設定爲true。設定完init方法後,開發者須要實現draw-in view方法。須要注意的是,此處並未直接將Metal材質傳入CIRenderDestination函數,而是建立了一個會返回texture的block。這使得CIContext能在前面的幀還沒有完成時將Metal工做入隊。以後該方法會執行渲染任務(至指定目的地)並建立command buffer將當前繪製結果渲染至view。

本人也親自嘗試了經過Core Image處理視頻的整個流程。如下案例使用CIVortexDistortion濾鏡對視頻進行逐幀處理並渲染,展現內容包含核心代碼、原視頻、CI濾鏡處理後視頻以及斷點測試的濾鏡逐幀處理圖示。

image

代碼1、測試核心代碼

3.pngimage.png

斷點調試時Core Image對每幀的處理流程

基於Metal構建Core Image Kernel

使用CI Kernel有諸多優點,包括上文說起的縮短runtime編譯時間、高性能語言特性(如gather-reads、group-writes、半精度浮點數)、高效開發體驗(如縮進檢查、縮進高光)。基於Metal構建CI Kernel有5步流程,會在下文進行逐一介紹。

1. 在項目中增長自定義構建規則

蘋果官方推薦在項目target中增長兩項自定義構建規則。第一個構建規則針對以「.ci.metal」爲後綴名的文件。該構建規則會建立一個以「.ci.air」爲後綴名的二進制輸出文件。

image.png

圖5、針對「*.ci.metal」文件的構建規則

第二個構建規則針對以「.ci.air」爲後綴名的文件(上一個構建規則的輸出結果)。該構建規則會在app的資源文件夾內建立以「.ci.metallib」爲後綴名的輸出文件。

image.png

圖6、針對「*.ci.air」文件的構建規則

2. 在項目中增長.ci.metal資源

在Xcode提供的建立面板中選擇Metal File便可。開發者對Metal File進行命名時須要以「.ci」做爲後綴名,這樣項目中新生成的文件會以「.ci.metal」做爲後綴名。

3. 編寫Metal Kernel

便攜Metal Kernel須要include CoreImage.h頭文件,用來使用Metal和Core Image提供的各類類。官方提供的範例編寫了一個CIColorKernel,輸入參數爲coreimage::samle_t對象(表示輸入圖片的一個像素)、time和coreimage::destination對象,返回float4像素。

image.png

圖7、蘋果官方提供的代碼範例:Metal Kernel編寫

蘋果官方爲開發者提供了描述CI Kernel中Metal Shader語言的文檔,詳情見「 Metal Shading Language for Core Image Kernels」。

4. 加載Kernel並應用於新圖像(基於Swift)

Kernel會被CI濾鏡的子類使用。蘋果官方推薦開發者在實例化濾鏡的CIKernel對象時使用靜態屬性(static property),這種狀況下加載metallib資源的工做僅會執行一次(在首次須要時)。CI濾鏡的子類也必須重載輸出圖片的屬性,Kernel將在getter中進行圖像處理並建立新圖像。

image.png

圖8、蘋果官方提供的代碼範例:Kernel加載與使用

Core Image的Debug支持

蘋果官方在WWDC20詳細介紹了Debug特性:CI_PRINT_TREE。

什麼是CI_PRINT_TREE

CI_PRINT_TREE的基礎框架與Xcode提供的Core Image Quick Look支持相同。Core Image Quick Look爲開發者提供了快捷可視化的Core Image圖片(詳見上文圖三),而CI_PRINT_TREE支持幾種不一樣的模式和選項用來查看Core Image如何優化和渲染圖像。

如何啓用CI_PRINT_TREE

蘋果官方提供了CI_PRINT_TREE的兩種啓動方式。最經常使用的方法是編輯Xcode target scheme,在Arugments窗體下的環境變量列表中加入CI_PRINT_TREE並設置值。另外一種方法是在Terminal.app中經過命令行啓動CI_PRINT_TREE(須要在執行應用程序前設定)。

image.png

image.png

圖9、啓用CI_PRINT_TREE的兩種方式

如何控制CI_PRINT_TREE

CI_PRINT_TREE的字符串格式爲「<graph type> <output type> <options>」

  1. graph type:表示Core Image render的若干stage,包括type-1初始圖像(有助於查看被使用的色彩空間)、type-2優化後的圖像(有助於查看core image對render的優化效果)、type-4級聯圖像(有助於查看各stage如何級聯於GPU程序,以便了解render須要多少中間緩存)以及type-7(輸出圖像type一、2和4)。

image.png

圖10、蘋果官方對graph type四個stage的描述

  1. output type:輸出格式能夠是pdf或png。在macOS上trees會被存儲在臨時項目文件夾,在iOS上trees會被存儲在文檔(Documents)目錄下。若是output type沒有肯定,core image會把tree以緊湊文本格式輸出在標準輸出(stdout)。經過設置CI_LOG_FILE="oslog",文本也能夠前往Console.app(在iOS開發中更爲方便)。
  2. options:對於CI_PRINT_TREE,開發者能夠設定額外的選項。如經過設定context==name來限制輸出(僅輸出名字相同的context),或是經過設定frame-n來框定具體輸出context的哪一幀。更多option及詳情請見圖十一。設定option對debug能提供很大幫助,但也需謹慎使用,由於生產這些文件須要額外的時間和內存。

image.png

圖11、蘋果官方提供的option

image.png

圖12、type設定爲7時tmp文件夾下的文件

如何得到CI_PRINT_TREE文件

在macOS中,開發者只須要進入「/tmp」文件夾就能找到生成的CI_PRINT_TREE文件。須要注意的是沙盒應用會使用特有的臨時存儲文件夾。在iOS中,開發者須要將Custom iOS Target Properties中的「Application supports iTunes file sharing」項設爲YES(圖十三)。這樣生成的CI_PRINT_TREE文件能夠在鏈接中的iOS設備上被找到並拖拽至macOS存儲中。

image.png

圖十3、Custom iOS Target Properties中進行設置

如何解釋CI_PRINT_TREE文件

讀CI_PRINT_TREE時,須要遵循如下規則:

  • 輸入在底層,輸出在頂層  
  • 綠色節點表明捲曲內核(warp kernel),紅色節點表明顏色內核(color kernel)

image.png

圖十4、綠色節點與紅色節點示例

  • 在樹的初始位置(initial tree)很容易找到顏色搭配節點(colormatch nodes),裏面記錄了搭配先後的色彩空間名稱。蘋果官方提供的案例爲ITUR_2100_HLG_to_workingspace,即HLG色彩空間轉化爲Core Image線性色彩空間。

image.png

圖十5、蘋果官方案例中initial tree對色彩空間的描述

  • 每一個節點會顯示Region of Interest(ROI),表示該節點在render中被使用的範圍。

若是開發者在CI_PRINT_TREE控制字符串中選擇type-4並在option中設定dump-intermediates,產生的級聯圖片會展現中間緩存的每一次pass(除了output pass)及其耗時、像素點數量和像素點格式(用來查找耗時大、佔內存大的pass)。這對render內追蹤錯誤很是有幫助。若是樹中沒有展現中間圖,那麼說明這張圖在先前渲染的時候已被緩存,所以Core Image沒有渲染它的必要。

image.png

圖十6、設定dump-intermediates的debug效果展現

Core Image在手淘圖片庫中的應用可能

手淘圖片庫中的CDN圖片適配處理庫(TBCDNImage)的核心目的是爲不一樣終端設備、網絡環境下的圖片展現提供最優解。目前考慮的維度主要是終端設備硬件和網絡狀態,考慮的參數則是圖片尺寸、壓縮比率、銳化等圖片屬性。隨着蘋果在Core Image、端智能(CoreML)、硬件支持(自研芯片)等方面進行技術提高,淘的CDN圖片適配處理庫能夠考慮增長「圖片內容」做爲新的維度,增加亮度、對比度、濾鏡、圖片種類等新參數。如下爲部分應用場景:

  • 識別亮度較暗的圖片,提高亮度作CDN圖片適配處理
  • 判斷圖片內容種類(如美食),根據不一樣內容種類的圖片增長適合的濾鏡作CDN圖片適配處理
  • 根據移動終端設備屏幕亮度(或深/淺色模式)修改圖片色調作CDN圖片適配處理,達到護眼效果

對Core Image技術的展望

總結全文,WWDC20對Core Image技術的提高主要在三方面:

  • 優化CI對視頻/動圖的支持,包括開發流程簡化、逐幀處理性能提高等。
  • 容許開發者更自由的構建Core Image Kernel,使CI的特效處理更加豐富
  • 針對CI開發流程提供更高效的Debug支持

隨着蘋果將來自研芯片的底層硬件支持將提供視頻流流暢的逐幀處理與渲染。筆者認爲Core Image技術將會在如下場景有較大應用價值:

  • 直播濾鏡/特效功能原生化(擺脫自研或第三方API),實現質量更高的實時濾鏡渲染
  • 視頻拍攝增長濾鏡功能(如淘寶或鹹魚的商品視頻錄製)

參考:

① https://developer.apple.com/m...

https://github.com/duzhaoquan...

團隊招人

手淘客戶端團隊正在進行社招招聘,崗位有iOS Android客戶端開發工程師、歡迎你們加入咱們。

簡歷投遞:junzhan.yzw@taobao.com

更多有關手淘的技術內容分享敬請關注VX公衆號【淘系技術】

相關文章
相關標籤/搜索