Overview of Quartz 2D

轉載請帶上出處, 謝謝.


Quartz 2D是一個二維圖形繪制引擎, 它支持iOS環境和Mac OS X非內核下的所有應用環境. 你可以使用 Quartz 2D API 來實現許多的功能, 例如基本路徑的繪制, 透明層, 描影, 繪制陰影, 透明層, 色彩管理, 抗鋸齒渲染, PDF 文檔生成和 PDF 元數據訪問. 在需要的時候, Quartz 2D 還可以利用圖形硬件的能力.
在 Mac OS X中, Quartz 2D 可以與其他圖形圖像技術混合使用, 例如Core Image, Core Video, OpenGL和QuickTime. 例如, 通過使用 QuickTime的GraphicsImportCreateCGImage函數,可以用 Quartz從一個 QuickTime圖形導入器中創建一個圖像. 詳情可以查看QuickTime Framework Reference . 移動Quartz 2D和Mac OS X中的Core Image之間的數據交換描述了如何能提供一個圖像來轉換成Core Image. (Core Image是一個支持圖像處理的框架. )
同樣地, 在IOS中, Quartz 2D與所有可用的圖形和動畫的技術可以混合使用,如Core Animation,OpenGL ES和UIKit類.


The Page



??Quartz 2D在圖像中使用了繪畫者模型(painter’s model). 在繪畫者模型中, 每個連續的繪制操作都是將一個繪制層(a layer of 'paint')放置于一個畫布('canvas'),我們通常稱這個畫布為(Page). Page上的繪圖可以通過添加繪圖操作來疊加更多繪圖來改變. 一個Page上的圖形對象除了通過疊加更多的繪圖來改變外別無他法. 這個模型允許你可以通過非常多小的圖元來構建超級復雜的圖形.

圖 1-1 展示了繪畫者模型如何工作. 在這個圖的上半部分, 左邊的圖像先被繪制上去然后再是實心的圖像. 結果除了一點點邊界實心的圖案把第一個圖案完全遮蓋的看不到了. 在這個圖的下半部分就是將反過來繪制, 讓實心的圖案先繪制. 正如你所看到的, 在繪畫者模式中繪制的順序是非常重要的.

Figure 1-1 繪畫者模型

painters_model.gif

Page可能是一張真的紙 (如果輸出設備是打印機); 它也有可能是一張虛擬的紙 (如果輸出設備是PDF文件); 它還可以是bitmap圖像. 這根據實際使用的graphics content 而定.


Drawing Destinations: The Graphics Context



??Graphics Context是一個不透明數據類型 (CGContextRef) , 用于封裝Quartz繪制圖像到輸出設備的信息, 例如 PDF 文件, bitmap 或者顯示器的窗口上. Graphics Context中的信息包括在Page中的圖像的圖形繪制參數和設備相關的表現形式. Quartz中的所有對象都是繪制或者包含到一個Graphics Context中.

你可以將Graphics Context當成一個繪制目標, 如圖 1-2所示.當你使用 Quartz 繪圖時, 所有設備相關的特性都包含在你所使用的Graphics Context中. 換句話說, 你可以簡單的將同一圖形畫到不同的設備上, 只需要提供不同的 Graphics Context 然后用一樣的順序進行Quartz繪圖. 你不用進行任何設備相關的計算; Quartz都替你做好了.

圖 1-2 Quartz 繪制目標

draw_destinations.gif

這些Graphics Context可以在你的應用程序中使用:
??? ? bitmap graphics context 允許你將RGB Colors,CMYK Colors,或灰度(grayscale)加到位圖(bitmap)中. 位圖(bitmap)是一個有像素組成的矩形陣列(rectangular array)(或柵格(raster)),每個像素都表示圖像中的一個點. 位圖圖像(bitmap image)也稱為樣本圖像(sampled image) . 更多詳情參見Creating a Bitmap Graphics Context.
??? ? PDF graphics context 允許你創建 PDF 文件. 在 PDF 文件中, 你的繪圖保留為命令的序列. PDF文件和位圖之間有一些顯著的差異:
????? ? PDF 文件不像位圖(bitmap)可能有且不止一張Page.
????? ? 當你在不同的設備上繪制PDF 的 Page時, 結果圖像會根據當前的設備來進行顯示特性優化.
????? ? PDF 文件的分辨率獨立性質—繪制的圖案大小可以無限的放大或者縮小而不犧牲圖像細節. 而用戶感知的位圖質量取決于當前正在被瀏覽的位圖的分辨率 .
???? 更多詳情參見 Creating a PDF Graphics Context.
??? ? window graphics context 是一個可以在窗口上繪制的Graphics Context. 請注意. 因為Quartz 2D 是一個圖形引擎而不是窗口管理系統, 你使用一個應用程序框架來獲得一個窗口的Graphics Context. 詳情查看 Creating a Window Graphics Context in Mac OS X .
??? ? layer context (CGLayerRef) 是一個與其他 Graphics Context有關聯的一個離屏繪制目標. 當給Graphics Context 繪制層的時候為了最佳的性能而被創建出來, 對于離屏繪制來說layer context是比bitmap graphics context更好的選擇. 詳情參見 Core Graphics Layer Drawing.
??? ? 當你想在 Mac OS X 中打印時, 你需要將你的內容發給 PostScript graphics context , 它由printing framework管理. 更多詳情參見 Obtaining a Graphics Context for Printing.


Quartz 2D 不透明數據類型



??除了 Graphics Contexts 外 Quartz 2D API 還定義了許多不透明數據類型. 由于這些API是 Core Graphics framework 的一部分, 所以這些數據類型和在這些之上的程序都是用CG開頭的.
??Quartz 2D 使用這些不透明數據類型來創建對象. 通過操作這些對象來獲得特定的繪制圖形. 圖 1-3 展示了3種使用Quartz 2D的繪制操作能獲得的圖像. 比如:
????? 你可以通過創建一個PDF Page對象來旋轉和展示它, 對 graphics context 應用旋轉操作, 并且要求 Quartz 2D將 page 繪制到 graphics context 中.
????? 你可以通過創建一個pattern對象來畫一個圖案, 定義構成pattern的形狀, 并且在繪制到Graphics Context是設置 Quartz 2D 使用這個pattern來繪制.
????? 您可以通過創建一個Shading對象來填充一個軸向或徑向的漸暈效應區域, 提供了一個確定漸暈上每個點顏色并且要求 Quartz 2D 使用這些顏色來填充Shading的函數.

圖 1-3 Quartz 2D 中的不透明數據類型是原生繪圖的基礎

drawing_primitives.gif

Quartz 2D 中的不透明數據類型包括以下這些 :
????? CGPathRef, 用于矢量圖,可以創建路徑,并進行填充(fill)或描畫(stroke).參見Paths
????? CGImageRef, 用于表示位圖圖像 (bitmap images) 和表示基于你提供的采樣數據的位圖圖像遮罩 (bitmap image masks) . 參見 Bitmap Images and Image Masks.
????? CGLayerRef, 用于表示能夠被重復繪制的 (如背景或模式(Pattern)) 和離屏繪制的繪制層. 參見 Core Graphics Layer Drawing
????? CGPatternRef, 用于重復繪制. 參見 Patterns.
????? CGShadingRefCGGradientRef, 用于繪制漸變. 參見 Gradients.
????? CGFunctionRef, 用于定義包含一個隨機的浮點值參數的回調函數 當你為shading創建gradients時使用這個數據類型. 參見 Gradients.
????? CGColorRefCGColorSpaceRef, 用于告訴 Quartz 怎么理解顏色. 參見 Color and Color Spaces.
????? CGImageSourceRefCGImageDestinationRef, 用于在 Quartz 中移動數據. 參見 Data Management in Quartz 2DImage I/O Programming Guide.
????? CGFontRef, 用于繪制文字, 參見 Text.
????? CGPDFDictionaryRef, CGPDFObjectRef, CGPDFPageRef, CGPDFStream, CGPDFStringRef, 和 CGPDFArrayRef, 提供了 PDF 元數據的訪問. 參見 PDF Document Creation, Viewing, and Transforming.
????? CGPDFScannerRefCGPDFContentStreamRef, 用于解析 PDF 元數據. 參見 PDF Document Parsing.
????? CGPSConverterRef, 用于將 PostScript 轉換成 PDF. 在 iOS 中不可用. 參見 PostScript Conversion.


Graphics States



?? Quartz 根據當前圖形狀態(current graphics state)中的參數來修改繪制操作的結果. 圖形狀態包含用于繪制程序的參數. 在 graphics context 上繪制的程序根據這些圖形狀態來確定怎么去渲染結果. 例如, 當你調用函數來填充顏色時, 你就改變了出存在當前圖形狀態中的值. 當前圖形狀態的其他常用元素還包括線寬、當前位置和文本字體大小.
?? graphics context 包含了一個圖形狀態棧. 當 Quartz 創建一個 graphics context 時, 這個棧是空的. 當你保存圖形狀態時, Quartz 將當前圖形狀態的一個副本壓入棧中. 當你還原圖形狀態時, Quartz 將棧頂的圖形狀態彈出棧. 棧頂的狀態就變成當前的圖像狀態.
要保存當前的圖形狀態, 可使用 CGContextSaveGState 函數來將當前圖形狀態的副本壓入棧中. 要還原以前保存的圖形狀態, 可以使用 CGContextRestoreGState 函數來用棧頂的狀態替換當前的圖形狀態.
請注意, 當前繪圖環境下的所有方面并不都是圖形狀態的元素. 例如, 當前路徑 (current path)就不是圖形狀態的一部分所以當你調用 CGContextSaveGState 時它并不會保存. 當你調用這個方法時, 圖形狀態會被保存的情況(即與圖形狀態相關聯的參數)參見 Table 1-1.
??Table 1-1 與圖形狀態相關聯的參數

參數 參見
Current transformation matrix(當前轉換矩陣) (CTM) Transforms
Clipping area(裁剪區域) Paths
Line: width, join, cap, dash, miter limit(線) Paths
Accuracy of curve estimation(曲線平滑度) (flatness) Paths
Anti-aliasing setting(抗鋸齒設置) Graphics Contexts
Color: fill and stroke settings(顏色設置) Color and Color Spaces
Alpha value(透明度) (transparency) Color and Color Spaces
Rendering intent(再現意圖) Color and Color Spaces
Color space: fill and stroke settings(顏色空間) Color and Color Spaces
Text: font, font size, character spacing, text drawing mode(文本) Text
Blend mode(混合模式) PathsBitmap Images and Image Masks

Quartz 2D 坐標系



??如 圖 1-4 所示的一個坐標系, 定義了被繪制到Page上的對象的位置及大小范圍. 你在用戶空間坐標系統 (user-space coordinate system) 指定圖像的位置和大小, 或者簡單點, 用戶空間 (user space) . 坐標值用浮點數來定義.
??圖 1-4 Quartz 坐標系

quartz_coordinates.gif

由于不同的設備成像能力也不同, 所有圖像的大小和位置必須以設備無關的方式定義. 例如, 一個屏幕顯示的設備可以顯示每英寸不超過96個像素, 雖然打印機可能能夠顯示每英寸300像素. 如果在設備級別上定義坐標系 (在這個例子中為96或者300), 則在一個設備上繪制的圖像無法在沒有明顯失真的情況下在其他設備顯示. 他們會顯得太大或者太小.
??Quartz 使用當前轉換矩陣 (current transformation matrix)或者說 CTM 將用戶空間 (user space) —將其映射到輸出設備的坐標系統—設備空間 (device space) 這種方式來解決設備的依賴. 矩陣是用來有效描述了一組相關方程的數學結構. 當前變換矩陣是一種特殊類型的矩陣被稱為仿射變換 (affine transform) . 通過平移(translation)、旋轉(rotation)、縮放(scale)操作將點從一個坐標空間映射到另外一個坐標空間 (calculations that move, rotate, and resize a coordinate system).
??當前轉換矩陣還有另一個目的: 它允許你通過旋轉來決定對象怎么被繪制. 例如 , 繪制一個旋轉了45度的盒子, 我們可以在繪制盒子之前旋轉Page(the CTM)的坐標系統。Quartz使用旋轉過的坐標系統來將盒子繪制到輸出設備中.
??在我們的坐標系中1個點被表示為一對坐標 (x,y), Quartz中默認的坐標系統是:沿著x軸從左到右坐標值逐漸增大, 沿著y軸從下到上坐標值逐漸增大, (0, 0)表示坐標原點. 原點位于 page 的左下角, 如 圖 1-4 所示.

一些技術在設置他們的 graphics contexts 時使用了不同于 Quartz 的默認坐標系. 相對于 Quartz 來說, 這些坐標系統是修改的坐標系統(modified coordinate system),當在這些坐標系統中顯示Quartz繪制的圖形時,必須進行轉換(補償). 最常見的一種修改的坐標系統是原點位于左上角, 而沿著y軸從上到下坐標值逐漸增大. 我們可以在如下一些地方見到這種坐標系統:
????? 在Mac OS X中,重寫過isFlipped方法以返回yes的NSView類的子類
????? 在IOS中,由UIView返回的繪圖上下文
????? 在IOS中,通過調用UIGraphicsBeginImageContextWithOptions函數創建的繪圖上下文 .

UIKit 以修改的坐標系統返回Quartz繪圖上下文的原因是因為UIKit中使用不同的默認坐標; 它適用與Quartz的變換. 如果應用程序想以相同的繪制程序在一個UIView對象和PDF Graphics Context上進行繪制 (都是用Quartz創建并且使用默認坐標系), 你需要做一個變換以使 PDF Graphics Contexts 接收到相同的坐標系. 要達到這一目的, 只需要對PDF的上下文的原點做一個平移(移到左上角)和用-1對y坐標值進行縮放. 例如 如果你調用 CGContextDrawImage 把一張圖片繪制進上下文, 當它被繪制到目標時, 這個圖片已經被變換修改了. Similarly, 路徑繪制程序接受一個在默認坐標系中順時針或者逆時針畫圓的參數. 如果坐標系被修改了, 那么就過也被修改了, 就像圖片被鏡子反射一樣. 在 ** 圖1-5 中** , passing the same parameters into Quartz results in a clockwise arc in the default coordinate system and a counterclockwise arc after the y-coordinate is negated by the transform.(不懂- -)
??圖 1-5 通過修改坐標系統創建鏡像圖像.

flipped_coordinates.jpg

你的應用程序負責調整 Quartz 調用以確保有一個轉換應用到上下文中. 例如, 如果你想要一個圖片或PDF正確的繪制到一個Graphics Context中, 你的應用程序可能需要臨時調整Graphics Context的CTM. 在iOS中, 如果你使用UIImage對象來包裹創建的CGImage對象, 你可以不需要去修改 CTM. The UIImage 對象將自動為修改的坐標系進行補償來適用 UIKit.

Important: 以上內容只是討論一些必要的內容讓你了解, 如果你打算直接在iOS上開發與Quartz相關的程序, 了解以上的討論是有用的但不是必須的. 在iOS 3.2 和后續的版本中, 當 UIKit 為你的應用程序創建了一個繪圖上下文時, 也對上下文進行了額外的修改來匹配 UIKit 的規定. 特別的, patterns 和 shadows, 都不被 CTM 所影響, 所以需要單獨進行調整來匹配 UIKit 的坐標系. 在這種情況下, 沒有一個等價的機制讓你的應用程序能使用 CTM 將通過 Quartz 創建的上下文和UIKit提供的上下文所匹配; 所以你的程序必須認識到什么樣的上下文正在進行繪制并且調整它的行為以匹配上下文的預期.


Memory Management: Object Ownership



??Quartz 使用 Core Foundation 的內存管理模型, 對對象使用引用計數. 當對象唄創建時, Core Foundation 對象一開始的引用計數為1. 你可以通過調用方法來retain對象達到增加計數的目的, 并且你也可以通過調用方法來release對象來達到減少技術的目的. 當引用計數遞減到0時, 這個對象就被釋放了. 這個模型允許對象被其他對象安全的引用.
??有幾個簡單的規則要記住:
????? 如果你創建活拷貝了一個對象, 你將擁有它, 因此你必須釋放他. 就是這樣, 通常, 如果你通過帶有 “Create” 或 “Copy” 的方法獲得對象, 當你使用完畢后必須釋放這些對象. 否則將導致內存泄露.
????? 如果不是通過帶有 “Create” 或 “Copy” 的方法獲得對象, 你將不會擁有對象的引用, 你將不會擁有對象的引用, 不需要釋放它, 這個對象會在未來的某個時刻由它的擁有者釋放.
????? 如果你不擁有一個對象而打算保持它, 你必須retain它并且在不需要的時候release掉它. 可以使用Quartz 2D的函數來指定retain和release一個對象. 例如, 如果你要引用一個 CGColorspace 對象, 則使用函數 CGColorSpaceRetainCGColorSpaceRelease 來 retain 和 release 對象, 你也可以使用 Core Foundation 的 CFRetainCFRelease 方法, 但是你必須要小心不要傳遞 NULL 給這些函數.

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

推薦閱讀更多精彩內容

  • Quartz 2D是一個二維繪圖引擎,可在iOS環境中和內核之外的所有Mac OS X應用程序環境中訪問。您可以使...
    權宜平和閱讀 519評論 0 0
  • 轉載請帶上出處, 謝謝. 一個 Graphics Context 代表一個繪制目標, 它包含繪制系統用于完成繪制指...
    Falme丶閱讀 1,819評論 0 2
  • 在Mac OS X中,Quartz 2D可以處理所有的圖形和圖形技術---Core Image,Core Vid...
    雪_晟閱讀 506評論 0 4
  • 對于《琵琶行》,有人說:一個官場失寵,一個情場失意;一個空有抱負,一個才藝擱置;一個京官被貶,一個遠嫁他鄉。驀然相...
    城隅候閱讀 4,029評論 0 17
  • 工作或者生活達到某個低潮的關頭,覺得自己已經無法再熬過這一切的時候,大腦中永遠浮現一個畫面。 20年前,做著肢體最...
    kk77閱讀 263評論 1 4