2012年1月24日 星期二

Filter4Cam 學習之 Core Image Programming Guide 1-1

since: 2012/01/23
update: 2012/01/24

reference: Core Image Programming Guide: Core Image Concepts

Core Image 概念之一

A. 導言
   1. 從 Mac OS X v10.4 開始, Core Image 是一個可用的能擴張的架構, 用來接近即時的
       , 像素-準確的(pixel-accurate) 對圖片及影片作影像處理. 你可以經由 Core Image
       內建的濾鏡或開發者自行建立的濾鏡來執行以下類型的操作:
       a. 裁切圖片(Crop images).
       b. 校正顏色, 例如: 執行白點調整(white point adjustment).
       c. 套用濾鏡, 像是褐色調(sepia tone).
       d. 模糊(Blur)或銳利(sharpen)圖片.
       e. 圖片合成(Composite).
       f. 對圖片變形(Warp)或幾何轉換(transform the geometry).
       g. 產生顏色, 象棋棋盤圖案, 高斯傾斜(Gaussian gradients), 及其它圖案的圖片.
       h. 對圖片或影片增加過渡特效(transition effects).
       i. 在影片上提供及時的顏色調整(color adjustment).

   2. Core Image 與其它圖像技術的關係:
      在 Mac OS X 中, Core Image 是與其它的圖像技術整合在一起, 允許一起使用來完成
      廣泛的結果. 例如: 你可以將由 Quartz 2D (Core Graphics) 建立的圖片以及由
      OpenGL 產生的紋理, 再經由 Core Image 來作影像處理; 你也可以將由 Core Video
      播放的影片, 套用 Core Image 的濾鏡.

   3. 這個章節提供 Core Image 技術的概觀, 並描述如何於應用程式中使用這個程式介面.
      也討論到 Core Image 如何在背景運作以完成快速, 令人震驚的, 近乎即時的影像處理.

-------------------------------------------------------------------------------------------------

B. Core Image 與 GPU
   1. OpenGL 直至目前為高效能 2D 與 3D 圖像的工業標準, 已經成為前往 GPU
      (graphics processing unit) 的主要通道. 在以往, 如果你想要使用 GPU 來作
      影像處理, 你需要知道 OpenGL Shading 語言. Core Image 改變了這一切, 因為
      有了 Core Image, 你不需要知道 OpenGL 的細解, 就可以駕馭 GPU 的力量來作
      影像處理. Core Image 自動地為你處理 OpenGL buffers狀態管理. 假如 GPU
      因為某些因素而無法使用, Core Image 會退而使用 CPU 以確保應用程式能執行.
      你的軟體僅僅是在運行, Core Image 的運作對你而言是不透明的(opaque).

   2. Core Image 提供了由 Objective-C 語言實作的簡易使用之 API, 因此隱藏了低階
       影像處理的細節. Core Image API 是 Quartz Core 框架 (QuartzCore.framework)
       的一部分, 你可以經由在 CocoaCarbon frameworks 中連結這個框架來使用
       Core Image.

-------------------------------------------------------------------------------------------------

C. 濾鏡委託人(Clients)與濾鏡創造者(Creators)
   1. Core Image 是設計給二種類型的開發者: 濾鏡委託人(filter clients)與濾鏡開發者
      (filter creators). 如果你打算只使用 Core Image 濾鏡, 你就是一個濾鏡委託人. 而
      如果你打算去寫自己的濾鏡, 那你就是濾鏡開發者. 這一章節將從每個類型的開發
      者觀點來敘述 Core Image 濾鏡, 並且提供使用 Core Image 需要知道的事情之概觀.

   2. Core Image 有超過 100 個內建的濾鏡, 可供濾鏡委託人在其應用程式上使用影像
       處理. 在 Core Image Filter Reference 中描述著那些濾鏡. 內建的濾鏡清單可以被
       更改, 因此之故, Core Image 提供了一個方法用來查詢系統中可用的濾鏡有哪些.
       你也可以載入第三方開發者的濾鏡套件當成影像單位(image units), 你會在這章節
       的後續讀到更多有關影像單位的內容.

   3. 你可以取得濾鏡清單或縮小查詢範圍來取得符合特定分類的濾鏡, 例如變形濾鏡
        (distortion filters) 或可與影片一同運作的濾鏡. 一個濾鏡的分類明確地說明了
       效果的種類: 模糊(blur), 變形(distortion), 產生器(generator), 等等, 或者預期要
       使用靜態圖片, 影片, 非方形像素(nonsquare pixels) 等等. 一個濾鏡可以是超過一
       種分類的成員. 濾鏡也有顯示名稱(display name), 用來在使用者界面上顯示;
       而濾鏡名稱(filter name)是用來以程式化的方式存取濾鏡名稱的. 你會在
        Using Core Image Filters 中, 知道如何去執行查詢.

   4. 大部分的濾鏡都有一個或多個輸入的參數, 用來控制如何完成影像處理. 每一個輸入
       的參數都有一個屬性類別(attribute class), 用來指明資料型別, 例如: NSNumber.
       輸入的參數可以選擇性地有其它的屬性, 例如: 預設值, 允許的最小和最大值, 參數的
       顯示名稱, 以及其它在 CIFilter 中描述的屬性.

   5. 舉例來說, 單色(color monochrome)濾鏡有三個輸入的參數: 待處理的影像, 單色
       顏色, 色彩飽和度(color intensity). 你除了提供影像, 還可選擇性地設定顏色與
       飽和度. 大部份的濾鏡, 包括單色濾鏡, 對於非影像的輸入參數都有預設值. 如果你
       不提供設定值給輸入的參數, Core Image 會使用預設值來處理影像.

   6. 濾鏡的屬性以鍵值成對(key-value pairs)的方式來儲存. 鍵是固定不變的, 用來識別
      不同的屬性; 而值的設定是搭配與鍵的組合. Core Image 屬性的值, 典型地是以下的
      資料型別之一:

      a. Strings (NSString objects): 例如: 顯示名稱(display names).

      b. Floating-point numbers (NSNumber data type): 用來指定數量(scalar), 如: 飽和度
          等級(intensity levels), 半徑(radii).

      c. Vectors (CIVector objects): 可以是 2 ~ 4 個元素(elements), 每個元素都是浮點數.
          用來指定位置, 地區與顏色值.

      d. Colors (CIColor objects): 指定顏色值與色彩空間(color space)來設值.

      e. Images (CIImage objects): 輕量級的物件, 用來指定影像的製作方法.

      f. Transforms (NSAffineTransform objects): 指定一個仿射的轉換來套用到影像上.

   7. Core Image 使用: 鍵-值編碼(key-value coding), 這意謂著: 藉由 NSKeyValueCoding
     協定
(protocol)所提供的方法, 你可以取得設定濾鏡的屬性值.
       註: Key-value coding 是 Objective-C 中用來存取物件屬性的機制. 為了有效地使用
             Core Image, 你必須熟悉 NSKeyValueCoding protocol, 更多資訊請看:
             Key-Value Coding Programming Guide.

   8. 典型的濾鏡組成成分:
      a. 上圖中, 所指出的色彩較暗地區是「藏在表面之下的機制或結構」(under the hood)
          ---- 這個部分, 濾鏡委託人可以不需要知道任何事, 但是濾鏡開發者必須瞭解的.
         沒有被遮蔽的部分, 有二個方法: attributesoutputImage, 是提供給濾鏡
         委託人呼叫的.

         濾鏡的 attributes 方法, 提供呼叫以獲得濾鏡屬性清單(之前討論過的), 包含濾鏡
         的輸入參數以及要在使用者介面上顯示的濾鏡名稱.

         outputImage 方法, 組合並儲存產生影像所必要的計算, 但實際上未促使
         Core Image 處理影像. 這是因為 Core Image 採用延遲求值的方式
         (
lazy evaluation). 換句話說, Core Image 直到實際要在目標上處理繪製像素的
         時刻到來時, 才會開始處理影像. outputImage 方法所做的所有事情就是: 組合
         繪製的時刻來臨時, Core Image 所需要的計算, 並且在 CIImage 物件中, 儲存這些
         計算(或影像製作方法). 當明確地去呼叫繪製影像的方法, 如:
         drawImage:atPoint:fromRect:drawImage:inRect:fromRect: , 實際的影像便
        會被描繪出來(因此, 計算就被執行了).

      b. Core Image 儲存了計算, 直到應用程式發佈要繪製影像的指令. 在那時, Core Image
          開始計算結果. 延遲求值是讓 Core Image 更快更有效率的實踐方式之一. 在描繪的
          時刻, Core Image 能夠知道是否有超過一個的濾鏡需要應用到影像上. 如果是的話,
          它可以連接複合的製作方法成為單一的操作, 這意謂著每個像素只會被處理一次,
          而不是許多次.

   9. 延遲求值的工作流程
          上圖, 說明了 lazy evaluation 如何在複合的操作中, 讓影像處理更有效率. 最後的
          影像是原始版本按比例縮減(scaled-down)的結果. 以一個大的影像為例, 在縮減
          影像尺寸之前先套用色彩調整濾鏡, 會比先縮減影像尺寸然後再套用色彩調整濾鏡
          需要更多的
處理能力. Core Image 會一直等待到最後一個可能套用濾鏡的時刻,
          然後能夠以相反的順序來執行操作, 這樣更有效率.

   10. 對濾鏡開發者而言, 在濾鏡中最令人興奮的組成成份是核心(kernel), 那是每個濾鏡
         的心臟. kernel 具體指定了會在每個原始影像像素執行的計算. Kernel 的計算可以
         是非常簡單或複雜. 一個不做任何事的濾鏡擁有非常簡單的 kernel, 這個 kernel 能夠
         簡單地傳回原始的像素: destination pixel = source pixel 

   11. 濾鏡開發者使用不同的 OpenGL Shading 語言 (glslang) 來詳細指明每個像素的
         計算. (請看: Core Image Kernel Language Reference.) 對濾鏡委託人而言, kernel
         是不透明的. 一個濾鏡實際上可以使用數個核心慣例(kernel routines), 將輸出的一
         方傳入輸入的另一方. 教導如何寫出客制的濾鏡, 請看: Creating a Custom Filter
         註: 濾鏡用來處理像素的 kernel 是實際上的例行程序, 由 Core Image 不同的
               glslang 所寫成. CIKernel 物件是一個包含有 kernel routine Core Image
               物件. 當你建立一個濾鏡時, 就會看到 kernel routine 存在於它自己的檔案裡, 其
               副檔名為 .cikernel. 藉著有計劃性地傳入包含著 kernel routine 的字串, 就可以
              建立一個 CIKernel 物件.

   12. 影像單位
          濾鏡開發者能夠使用 NSBundle 類別所指定結構 藉由將濾鏡套裝成外掛
          影像單位(
image unit), 來讓客制的濾鏡供其它的應用程式使用. 如上圖所示, 一個
          影像單位可以包含超過一個的濾鏡. 舉例來說, 你可以寫一套濾鏡用來執行不同種類
          的邊緣偵測(edge detection), 並且將它們套裝成一個影像單位. 濾鏡委託人可以
          使用 Core Image API 來將影像單位載入, 並且獲得在其影像單位中的濾鏡清單.
          參考 Loading Image Units 來得到基本的資訊. 參考 Image Unit Tutorial , 有更
          深入的範例與詳細的資訊用來寫出濾鏡並將其套裝成獨立的
影像單位.  

© 2004, 2011 Apple Inc. All Rights Reserved. (Last updated: 2011-10-12)

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。