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