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從QuickTime圖形導入器在Quartz中創建圖像。有關詳細信息,請參閱QuickTime Framework Reference。在Mac OS X中在Quartz 2D和Core Image之間移動數據描述了如何向Core Image提供圖像,Core Image是一個支持圖像處理的框架。
類似地,在iOS中,Quartz 2D使用所有可用的圖形和動畫技術,例如Core Animation,OpenGL ES和UIKit類。
The Page
Quartz 2D使用畫家的模型進行成像。 在畫家模型中,每個連續的繪制操作將一層“繪畫”應用于輸出“畫布”,通常稱為頁面。 頁面上的油漆可以通過額外的繪圖操作覆蓋更多的油漆來修改。 在頁面上繪制的對象不能被修改,除非重疊更多的顏色。 此模型允許您從少量強大的圖元構造非常復雜的圖像。
圖1-1顯示了畫家的模型如何工作。 為了在圖的頂部獲得圖像,首先繪制左邊的形狀,然后繪制實心形狀。 實心形狀覆蓋第一形狀,遮蔽第一形狀的周邊以外的所有邊界。 在圖的底部以相反的順序繪制形狀,首先繪制實心形狀。 正如你可以看到,在畫家的模型中,繪圖順序很重要。
頁面可以是真正的紙張(如果輸出設備是打印機); 它可以是虛擬紙(如果輸出設備是PDF文件); 它甚至可以是位圖圖像。 頁面的確切性質取決于您使用的特定圖形上下文。
繪圖目的地:圖形上下文(The Graphics Context)
圖形上下文是一種不透明數據類型(CGContextRef),它封裝了Quartz用于將圖像繪制到輸出設備的信息,例如PDF文件,位圖或顯示器上的窗口。 圖形上下文中的信息包括頁面上的涂料的圖形繪制參數和設備特定表示。 Quartz中的所有對象都被繪制到或包含在圖形上下文中。
您可以將圖形上下文視為繪圖目標,如圖1-2所示。 當您使用Quartz繪制時,所有特定于設備的特性都包含在您使用的特定類型的圖形上下文中。 換句話說,只需向Quartz繪圖例程的同一序列提供不同的圖形上下文,即可將同一圖像繪制到不同的設備。 您不需要執行任何設備特定的計算; Quartz為你做。
這些圖形上下文可供您的應用程序使用:
- ** bitmap graphics context **允許您將RGB顏色,CMYK顏色或灰度繪制到位圖中。位圖是像素的矩形陣列(或光柵),每個像素表示圖像中的點。位圖圖像也稱為采樣圖像。請參閱創建位圖圖形上下文。
- ** PDF graphics context **允許您創建PDF文件。在PDF文件中,您的繪圖將保留為一系列命令。 PDF文件和位圖之間存在一些顯著差異:
- PDF文件與位圖不同,可能包含多個頁面。
- 當您從其他設備上的PDF文件中繪制頁面時,生成的圖像會針對該設備的顯示特性進行優化。
- PDF文件是本質上獨立的分辨率 - 它們繪制的大小可以無限增加或減少,而不會犧牲圖像細節。位圖圖像的用戶感知質量與打算觀看位圖的分辨率相關。
請參閱創建PDF圖形上下文。
- ** window graphics context **是一個圖形上下文,您可以使用它來繪制窗口。注意,因為Quartz 2D是一個圖形引擎而不是一個窗口管理系統,你使用一個應用程序框架來獲取一個窗口的圖形上下文。有關詳細信息,請參閱在Mac OS X中創建窗口圖形上下文。
- ** *layer context * **(CGLayerRef)是與另一圖形上下文相關聯的離屏繪制目的地。它被設計為在將圖層繪制到創建它的圖形上下文時獲得最佳性能。對于屏幕外繪制,層上下文可以是比位圖圖形上下文更好的選擇。請參閱Core Graphics Layer Drawing。
- 當您要在Mac OS X中打印時,您將內容發送到由打印框架管理的PostScript圖形上下文。有關詳細信息,請參閱獲取打印的圖形上下文
Quartz 2D不透明數據類型
除了圖形上下文,Quartz 2D API還定義了各種不透明的數據類型。 因為API是Core Graphics框架的一部分,所以操作它們的數據類型和例程使用CG前綴。
Quartz 2D從您的應用程序操作的不透明數據類型創建對象,以實現特定的圖形輸出。 圖1-3顯示了對Quartz 2D提供的三個對象應用繪制操作時可以實現的結果類型。 例如:
- 您可以通過創建PDF頁面對象,對圖形上下文應用旋轉操作,并要求Quartz 2D將頁面繪制到圖形上下文來旋轉和顯示PDF頁面。
- 您可以通過創建模式對象,定義組成模式的形狀,并設置Quartz 2D,以便在繪制圖形上下文時將模式用作繪畫來繪制模式。
- 您可以通過創建陰影對象,提供一個確定陰影中每個點的顏色的函數,然后要求Quartz 2D將陰影用作填充顏色,通過軸向或徑向陰影填充區域。
Quartz 2D中可用的不透明數據類型包括:
- CGPathRef,用于矢量圖形創建您填充或描邊的路徑。請參閱路徑。
- CGImageRef,用于基于您提供的樣本數據表示位圖圖像和位圖圖像掩碼。請參閱位圖圖像和圖像掩碼。
- CGLayerRef,用于表示可用于重復繪圖(例如用于背景或圖案)和離屏繪制的繪圖圖層。請參閱Core Graphics Layer Drawing
- CGPatternRef,用于重復繪圖。請參閱模式。
- CGShadingRef和CGGradientRef,用于繪制漸變。請參閱漸變。
- CGFunctionRef,用于定義具有任意數量的浮點參數的回調函數。在為陰影創建漸變時,使用此數據類型。請參閱漸變。
- CGColorRef和CGColorSpaceRef,用于告知Quartz如何解釋顏色。請參閱顏色和顏色空間。
- CGImageSourceRef和CGImageDestinationRef,用于將數據移入和移出Quartz。請參閱Quartz 2D和Image I / O編程指南中的數據管理。
- CGFontRef,用于繪制文本。參見文本。
- CGPDFDictionaryRef,CGPDFObjectRef,CGPDFPageRef,CGPDFStream,CGPDFStringRef和CGPDFArrayRef,它們提供對PDF元數據的訪問。請參閱PDF文檔創建,查看和轉換。
- CGPDFScannerRef和CGPDFContentStreamRef,用于解析PDF元數據。請參閱PDF文檔解析。
- CGPSConverterRef,用于將PostScript轉換為PDF。它不適用于iOS。請參閱PostScript轉換。
圖形狀態
Quartz根據當前圖形狀態下的參數修改繪圖操作的結果。圖形狀態包含將被作為繪圖例程的參數。繪制到圖形上下文的例程參考圖形狀態以確定如何呈現其結果。例如,當您調用函數設置填充顏色時,您正在修改存儲在當前圖形狀態中的值。當前圖形狀態的其他常用元素包括線寬,當前位置和文本字體大小。
圖形上下文包含一疊圖形狀態。當Quartz創建一個圖形上下文時,堆棧是空的。當保存圖形狀態時,Quartz將當前圖形狀態的副本推送到堆棧。當你恢復圖形狀態,Quartz從堆棧的頂部彈出圖形狀態。彈出狀態變為當前圖形狀態。
要保存當前圖形狀態,請使用函數CGContextSaveGState將當前圖形狀態的副本推送到堆棧。要恢復以前保存的圖形狀態,請使用函數CGContextRestoreGState將當前圖形狀態替換為位于堆棧頂部的圖形狀態。
注意,并非當前繪圖環境的所有方面都是圖形狀態的元素。例如,當前路徑不被視為圖形狀態的一部分,因此在調用函數CGContextSaveGState時不會保存。調用此函數時保存的圖形狀態參數如下表所示。
Quartz 2D坐標系
坐標系統,如圖1-4所示,定義了用于表示頁面上要繪制的對象的位置和大小的位置范圍。 您可以在用戶空間坐標系中指定圖形的位置和大小,或者更簡單地指定用戶空間。 坐標定義為浮點值。
因為不同的設備具有不同的底層成像能力,所以必須以設備無關的方式定義圖形的位置和大小。例如,屏幕顯示設備可能能夠每英寸顯示不超過96個像素,而打印機可能能夠顯示每英寸300個像素。如果在設備級別定義坐標系(在此示例中為96像素或300像素),則在該空間中繪制的對象如果在其他設備上再現。它們將顯得太大或太小。
Quartz通過使用當前的變換矩陣或CTM,通過單獨的坐標系統(用戶空間映射)將輸出設備的坐標系統(設備空間)完成設備獨立性。矩陣是用于有效描述一組相關方程的數學構造。當前變換矩陣是稱為仿射變換的特定類型的矩陣,其通過應用平移,旋轉和縮放操作(移動,旋轉和調整坐標系統的計算)將點從一個坐標空間映射到另一個坐標空間。
當前的變換矩陣有第二個目的:它允許你轉換對象的繪制方式。例如,要繪制旋轉45度的框,您在繪制框之前旋轉頁面的坐標系(CTM)。 Quartz使用旋轉的坐標系統繪制到輸出設備。
用戶空間中的點由坐標對(x,y)表示,其中x表示沿水平軸(左和右)的位置,y表示垂直軸(上下)。用戶坐標空間的原點是點(0,0)。原點位于頁面的左下角,如圖1-4所示。在Quartz的默認坐標系中,x軸隨著從頁面的左側向右側移動而增加。當y軸從頁面的底部向頂部移動時,y軸的值增加。
一些技術使用與Quartz使用的默認坐標系不同的默認坐標系來設置它們的圖形上下文。相對于Quartz,這樣的坐標系是修改的坐標系,并且當執行一些Quartz繪圖操作時必須被補償。最常見的修改坐標系將原點放置在上下文的左上角,并將y軸更改為指向頁面底部。您可能會看到這個特定坐標系統的幾個地方如下:
- 在Mac OS X中,NSView的子類覆蓋其isFlipped方法以返回YES。
- 在iOS中,由UIView返回的繪圖上下文。
- 在iOS中,通過調用UIGraphicsBeginImageContextWithOptions函數創建的繪圖上下文。
UIKit返回具有修改的坐標系的Quartz繪圖上下文的原因是UIKit使用不同的默認坐標約定;它將變換應用到它創建的Quartz上下文,以便它們匹配其約定。如果應用程序想要使用相同的繪圖例程來繪制到UIView對象和PDF圖形上下文(由Quartz創建并使用默認坐標系),則需要應用變換,以便PDF圖形上下文接收相同的修改坐標系。為此,應用將原點轉換為PDF上下文左上角的變換,并將y坐標按-1縮放。
使用縮放變換來否定y坐標改變了Quartz圖形中的一些約定。例如,如果調用CGContextDrawImage將圖像繪制到上下文中,則在繪制到目標中時,圖像將被變換修改。類似地,路徑繪制例程接受指定是否在默認坐標系中沿順時針或逆時針方向繪制弧的參數。如果坐標系被修改,結果也被修改,好像圖像被反射鏡反射。在圖1-5中,將相同的參數傳遞到Quartz將導致默認坐標系中的順時針圓弧和y坐標被變換取反后的逆時針圓弧。
它是由你的應用程序來調整任何Quartz調用它對應用了一個變換的上下文。 例如,如果您想要將圖像或PDF正確繪制到圖形上下文中,則應用程序可能需要臨時調整圖形上下文的CTM。 在iOS中,如果使用UIImage對象包裝您創建的CGImage對象,則不需要修改CTM。 UIImage對象自動補償UIKit應用的修改后的坐標系。
重要:上面的討論對于了解你是否計劃編寫直接針對Quartz在iOS上的應用程序至關重要,但這是不夠的。 在iOS 3.2及更高版本上,當UIKit為應用程序創建繪圖上下文時,還會對上下文進行其他更改以匹配默認的UIKIt約定。 特別地,不受CTM影響的模式和陰影被單獨調整,使得它們的約定匹配UIKit的坐標系。 在這種情況下,沒有與CTM的等效機制,您的應用程序可以使用它來更改由Quartz創建的上下文以匹配UIKit提供的上下文的行為; 您的應用程序必須識別它正在繪制什么樣的上下文,并調整其行為以匹配上下文的期望。
內存管理:對象所有權
Quartz使用Core Foundation內存管理模型,其中對象被引用計數。 創建時,Core Foundation對象以引用計數1開始。您可以通過調用函數來保留對象來增加引用計數,并通過調用函數釋放對象來減少引用計數。 當引用計數減少到0時,對象被釋放。 此模型允許對象安全地共享對其他對象的引用。
有幾個簡單的規則要記住:
- 如果您創建或復制對象,則您擁有它,因此您必須釋放它。也就是說,一般來說,如果從名稱中包含單詞“Create”或“Copy”的函數中獲取對象,則必須在完成該對象后釋放該對象。否則,將導致內存泄漏。
- 如果從名稱中不包含單詞“Create”或“Copy”的函數獲取對象,則不具有對對象的引用,并且不能釋放它。對象將在未來的某個時間由其所有者釋放。
- 如果你沒有一個對象,你需要保持它的時候,你必須保留它,并當你完成它的時候,釋放它。您使用特定于對象的Quartz 2D函數來保留和釋放該對象。例如,如果接收到對CGColorspace對象的引用,則可以使用函數CGColorSpaceRetain和CGColorSpaceRelease根據需要保留和釋放對象。您還可以使用Core Foundation函數CFRetain和CFRelease,但是必須小心不要將NULL傳遞給這些函數。