???????????? 在Mac OS X中,Quartz 2D可以處理所有的圖形和圖形技術(shù)---Core Image,Core Video,OpenGL,QuickTime。可以使用QuickTime GraphicsImportCreateCGImage函數(shù)創(chuàng)建一個(gè)圖形通過QucikTime Framework 的入口。有關(guān)詳細(xì)信息,可以參照QuickTime Framework的引用。在Mac OS X上在Quartz 2D 和 Core Image 交換數(shù)據(jù)形象描述了如何為Core Image提供圖像。(這是一個(gè)框架,支持圖像處理)。
??????????? 同樣,在iOS中,Quartz 2D 可以使用所有可用的圖形和動(dòng)畫技術(shù),如核心動(dòng)畫,OpenGL ES,和UIKit 類;
概述里主要介紹:
? ?? 1.? ?? ? The Page(頁面)
? ?? 2.????? Graphics States 圖形狀態(tài)
? ?? 3.?????? Quartz 2D Opaque Data Types Quartz 2D 不透明? 數(shù)據(jù)類型
? ?? 4.? ? ?? Quartz 2D Coordinate Systems? 坐標(biāo)系統(tǒng)
???? 5.??????? Memory Management: Object Ownership? 內(nèi)存管理對(duì)象所有權(quán)
????????? The Page(頁面)
? ? ? ? ? Quartz 2D 在成像過程中使用了繪畫模型,在繪畫模型中,每一個(gè)連續(xù)的繪圖操作適用于layer 層的繪制到畫布的輸出,這經(jīng)常被稱作畫布。額外的繪圖操作可以覆蓋原有頁面上的繪圖。這個(gè)模型允許你從一個(gè)小數(shù)量的強(qiáng)大的原語構(gòu)造非常復(fù)雜的圖像。
?? 圖1-1顯示了 繪圖模型是如果工作的, 上面的圖中后來的固體形狀覆蓋了第一個(gè)圖,只留下了邊界。下滿的圖 后面的形狀在固體形狀中得以保留。所以畫圖的順序是很重要的。

頁面可能是一個(gè)真正的紙(如果輸出設(shè)備是一臺(tái)打印機(jī));這可能是一個(gè)虛擬的紙(如果輸出設(shè)備是一個(gè)PDF文件),甚至可能是一個(gè)位圖圖像。頁面的確切性質(zhì)取決于您所使用的特定的圖形上下文。? ?
Drawing Destinations: The Graphics Context 繪制的目的地:圖形上下文
? 圖形上下文是一個(gè)不透明的數(shù)據(jù)類型(CGContextRef)這個(gè)數(shù)據(jù)類型封裝了使用Quartz 2D輸出到設(shè)備上的信息,比如PDF文件,位圖,或在顯示窗口。圖形上下文的信息包含了圖形繪制參數(shù)和特定的設(shè)備展示在繪制頁面上。Quartz 2D 里的所有對(duì)象都被繪制包括圖形上下文。
你可以把一個(gè)圖形上下文想象為一個(gè)繪圖目標(biāo),如圖1-2所示。當(dāng)您使用Quartz 2D時(shí),所有的設(shè)備特定的特性都包含在您使用的特定類型的圖形上下文中。換言之,你可以通過提供一個(gè)不同的圖形上下文來繪制相同的圖像到一個(gè)不同的設(shè)備相同的順序的Quartz 2D繪圖程序。您不需要執(zhí)行任何設(shè)備特定的計(jì)算,Quartz 2D為您做的。

????????? 這些圖形上下文都可以在你的應(yīng)用程序中用到:
? ? ? Abitmap graphics context 位圖圖形上下文允許你繪制RGB、CMYK顏色或灰度圖轉(zhuǎn)化為位圖。位圖是一個(gè)像素的矩形陣列(或光柵),每一個(gè)像素代表一個(gè)圖像中的一個(gè)點(diǎn)。位圖圖像也被稱為采樣圖像。請(qǐng)參考Creating a Bitmap Graphics Context。?
? ? 一個(gè)PDF圖形上下文允許你創(chuàng)建一個(gè)PDF文件。在一個(gè)PDF文件,你畫的圖保存為一個(gè)命令序列。有PDF文件和位圖的一些顯著的差異 : ?
? ? ?? PDF文件,不像位圖,可以包含多個(gè)頁面。
? ? ? 當(dāng)你畫一個(gè)頁面在不同的設(shè)備上的PDF文件,得到的圖像是該設(shè)備的顯示特性優(yōu)化。
? ? ? PDF文件本質(zhì)上是分辨率獨(dú)立的,被繪制的大小可以無限增加或者減少,而不用犧牲圖像細(xì)節(jié)。位圖圖像的用戶感知質(zhì)量與位圖的被瀏覽的分辨率聯(lián)系在一起。請(qǐng)參考Creating a PDF Graphics Context。
? ? ? 一個(gè)窗口圖形上下文是一個(gè)圖形上下文,可以用來繪制一個(gè)窗口。請(qǐng)注意,因?yàn)槭⑹且粋€(gè)圖形引擎,而不是一個(gè)窗口管理系統(tǒng),你使用的應(yīng)用程序框架之一來獲得一個(gè)窗口的圖形上下文。SeeCreating a Window Graphics Context in Mac OS Xfor details.
??????? A layer context (CGLayerRef)? ? 層的上下文是一個(gè)離屏繪制與另一個(gè)圖形上下文相關(guān)的目的地。當(dāng)你把layer 繪制到它所創(chuàng)建的上下文的時(shí)候,性能是最佳的。對(duì)于離屏繪制來說,layer congtext 比起位圖上下文來說是個(gè)更好地選擇。SeeCore Graphics Layer Drawing。
? ????? 當(dāng)你想在Mac OS X 上打印時(shí),你把內(nèi)容發(fā)送給PostScript graphics context(被打印框架管理)。SeeObtaining a Graphics Context for Printingfor more information。
? ? Quartz 2D Opaque Data Types Quartz 2D 不透明? 數(shù)據(jù)類型
? ????? Quartz 2D 除了定義圖像上下文之外還定義了各種不透明的數(shù)據(jù)類型。應(yīng)為API是? CoreGraphics框架的一部分,數(shù)據(jù)類型和操作例程都使用CG前綴。
???????? Quartz 2D根據(jù)我們需要操作的數(shù)據(jù)類型進(jìn)行創(chuàng)建,已實(shí)現(xiàn)一個(gè)特性的繪圖輸出。
???????? 圖1-3顯示了你可以實(shí)現(xiàn)的結(jié)果當(dāng)你應(yīng)用繪圖操作三個(gè)Quartz 2D對(duì)象的情況:
? ? ? ? ? ? ? ? (1):你可以旋轉(zhuǎn),通過創(chuàng)建一個(gè)PDF頁面對(duì)象顯示PDF頁面,應(yīng)用旋轉(zhuǎn)操作的圖形上下文,并要求Quartz 2D繪制頁面圖形上下文。
? ? ? ? ? ? ? ? (2):可以通過創(chuàng)建一個(gè)模式對(duì)象來繪制模式,定義構(gòu)成模式的形狀,并在繪制圖形上下文時(shí)設(shè)置一個(gè)用于繪制圖形的Quartz 2D圖形。
? ? ? ? ? ? ? ? (3) :您可以通過創(chuàng)建一個(gè)陰影對(duì)象(提供了決定陰影中每個(gè)點(diǎn)的顏色的方法)來填充一個(gè)軸向或徑向的陰影區(qū)域,然后要求陰影對(duì)象作為填充顏色。
?

???? Quartz 2D? 中可用的不透明的數(shù)據(jù)類型有一下幾種 :
? ? ? ? CGPathRef : 用來創(chuàng)建你填充或者描邊的矢量圖形;SeePaths.
? ? ? ?? CGImageRef:? 用來表示位圖圖像和基于你提供的樣本數(shù)據(jù)的位圖掩模。SeeBitmap Images and Image Masks.。
? ? CGLayerRef:用來表示一個(gè)圖層,可用于重復(fù)繪制(如背景或模式)和離屏繪制。SeeCore Graphics Layer Drawing;
? CGPatternRef:用于重復(fù)繪制,SeePatterns.
CGShadingRef and CGGradientRef:用來繪制漸變,SeeGradients.
CGFunctionRef:用于定義回調(diào)函數(shù),以浮點(diǎn)任意參數(shù)。當(dāng)您創(chuàng)建漸變的陰影時(shí),您使用此數(shù)據(jù)類型。SeeGradients.
CGColorRef and CGColorSpaceRef:用來告知Quartz 2D如何解析顏色。SeeColor and Color Spaces.
CGImageSourceRef and CGImageDestinationRef:你可以用它來將數(shù)據(jù)移入和移出Quartz 2D。在Quartz 2D和圖像I / O編程指南中看到數(shù)據(jù)管理。SeeData Management in Quartz 2DandImage I/O Programming Guide.
CGFontRef:用于繪制文本;SeeText.
CGPDFDictionaryRef, CGPDFObjectRef, CGPDFPageRef, CGPDFStream, CGPDFStringRef, and CGPDFArrayRef:它提供了訪問PDF元數(shù)據(jù),SeePDF Document Creation, Viewing, and Transforming.
CGPDFScannerRef and CGPDFContentStreamRef:解析PDF元數(shù)據(jù),SeePDF Document Parsing
CGPSConverterRef:在iOS不可用,SeePostScript Conversion.
Graphics States 圖形狀態(tài)
???????? Quartz 2D修改繪圖操作的結(jié)果根據(jù)當(dāng)前圖形狀態(tài)的參數(shù)。圖形狀態(tài)包含參數(shù),否則被視為繪圖程序的參數(shù)。例程比如畫一個(gè)圖形上下文需要參考圖形狀態(tài)來決定如何渲染他們的結(jié)果。例如,當(dāng)你調(diào)用一個(gè)函數(shù)來設(shè)置填充顏色,你修改的值存儲(chǔ)在當(dāng)前圖形狀態(tài),所以得參考當(dāng)天圖形狀態(tài)。其他常用元素的當(dāng)前圖形狀態(tài)包括線寬、當(dāng)前位置、文本字體大小。
???????? 圖形上下文包含一個(gè)圖形狀態(tài)的堆棧,當(dāng)你創(chuàng)建圖形上下文時(shí),堆棧 是空的,當(dāng)你保存圖形狀態(tài)時(shí),Quartz把當(dāng)前圖形狀態(tài)拷貝一份并且推到棧頂上。當(dāng)你恢復(fù)圖形狀態(tài)時(shí),Quartz 把圖形狀態(tài)推出棧頂,推出的狀態(tài)成為當(dāng)前的圖形狀態(tài);
? ? ? ? 保存當(dāng)前的圖形狀態(tài),使用方法CGContextSaveGState,拷貝一份當(dāng)前圖形狀態(tài)并且推到棧上。為了恢復(fù)之前保存的圖形狀態(tài),使用方法CGContextRestoreGState用棧頂?shù)膱D形狀態(tài)替換當(dāng)前的圖形狀態(tài)。
? ? ? 請(qǐng)注意,不是當(dāng)前繪圖環(huán)境的所有方面都是圖形狀態(tài)的元素。例如,當(dāng)前的路徑是不被認(rèn)為是圖形狀態(tài)的一部分,因此也沒有保存當(dāng)你調(diào)用函數(shù)CGContextSaveGState的時(shí)候。當(dāng)你調(diào)用這個(gè)函數(shù)的時(shí)候能夠被保存的參數(shù)在下列的列表中:
?

Quartz 2D Coordinate Systems?? 坐標(biāo)系統(tǒng)
一個(gè)坐標(biāo)系,圖1-4所示,定義了用于表示位置和大小的物體被繪制在頁面上的位置范圍。您指定在用戶空間坐標(biāo)系中的圖形的位置和大小,或者,更簡(jiǎn)單地說,用戶空間。坐標(biāo)被定義為浮點(diǎn)值。

由于不同的設(shè)備有不同的底層成像能力,圖形的位置和大小必須以設(shè)備無關(guān)的方式定義。例如,一個(gè)屏幕顯示設(shè)備可能能夠顯示不超過96像素每英寸,而一臺(tái)打印機(jī)可能是能夠顯示每英寸300像素。如果您在設(shè)備級(jí)定義坐標(biāo)系統(tǒng)(在這個(gè)例子中,或者96像素或300像素),在該空間中繪制的對(duì)象不能被復(fù)制在其他設(shè)備上而沒有可見的失真。他們會(huì)顯得太大或太小。
Quartz完成設(shè)備獨(dú)立性通過一個(gè)分離開來的坐標(biāo)系統(tǒng)----用戶空間 ---映射到輸出設(shè)備的坐標(biāo)系統(tǒng)---設(shè)備空間---采用當(dāng)前的變換矩陣,或者CTM。矩陣是一個(gè)數(shù)學(xué)結(jié)構(gòu),用來有效地描述一組相關(guān)的方程組。當(dāng)前變換矩陣是一種特殊類型的矩陣,稱為仿射變換,它映射點(diǎn)從一個(gè)坐標(biāo)空間到另一個(gè)通過應(yīng)用平移,旋轉(zhuǎn)和縮放操作(計(jì)算,移動(dòng),旋轉(zhuǎn),調(diào)整坐標(biāo)系統(tǒng))。
當(dāng)前的變換矩陣有一個(gè)次要目的:它允許你在繪制對(duì)象的時(shí)候進(jìn)行旋轉(zhuǎn)。例如,畫一個(gè)旋轉(zhuǎn)45°的框的時(shí)候,在畫框之前旋轉(zhuǎn)了當(dāng)前頁面的坐標(biāo)系統(tǒng),Quartz在輸出設(shè)備上使用的就是旋轉(zhuǎn)后的坐標(biāo)系。
在用戶空間中的一個(gè)點(diǎn)表示的坐標(biāo)對(duì)(X,Y),其中X代表沿水平軸(左和右)和Y的位置和Y代表垂直軸(上下)。用戶坐標(biāo)空間的原點(diǎn)是(0,0)的點(diǎn)。原點(diǎn)坐落在頁面的左下角,如圖1-4所示。Quartz默認(rèn)的坐標(biāo)系統(tǒng),在頁面中,它從左到右的X軸增加在Y軸的增加值從底部向頂部。
一些技術(shù)使用不同的默認(rèn)坐標(biāo)系統(tǒng)來設(shè)置他們的圖形上下文,而不是Quartz默認(rèn)的坐標(biāo)系統(tǒng)。相對(duì)于Quartz,這樣的坐標(biāo)系統(tǒng)是一個(gè)修改的坐標(biāo)系,在執(zhí)行一些繪圖操作必須進(jìn)行補(bǔ)償。最常見的修改坐標(biāo)系統(tǒng)是 左上角是原點(diǎn),沿著y軸指向頁面底部。一些地方,你可能會(huì)看到這個(gè)特定的坐標(biāo)系統(tǒng)使用的是:
????????? 1°:在Mac OS X中,一個(gè)NSView的重寫了它的isFlipper方法并且返回YES的子類的時(shí)候。
????????? 2°:iOS中,由一個(gè)UIView返回的繪圖上下文。
? ? ? ? ? 3°:iOS中,繪圖上下文調(diào)用UIGraphicsBeginImageContextWithOptions函數(shù)創(chuàng)建。
? 為什么UIKit框架修改了坐標(biāo)系統(tǒng)是因?yàn)閁IKit使用不同的默認(rèn)坐標(biāo)習(xí)慣。它轉(zhuǎn)換了Quartz的坐標(biāo)系統(tǒng)使之能夠匹配自己的習(xí)慣。假如你的應(yīng)用需要使用相同的繪圖程序繪制一個(gè)UIView和一個(gè)PDF圖形上下文(它通過Quartz創(chuàng)建,使用的是默認(rèn)的坐標(biāo)系統(tǒng)),你需要轉(zhuǎn)換PDF上下文的坐標(biāo)系統(tǒng)和UIView 的坐標(biāo)系統(tǒng)一樣。為此,你需要轉(zhuǎn)換PDF上下文的坐標(biāo)原點(diǎn)到左上角和y軸的方向。 ???????????????????????
使用縮放變化否定了在Quartz繪圖時(shí)y坐標(biāo)的改變。舉個(gè)例子,在你調(diào)用CGContextDrawImage繪制的時(shí)候,當(dāng)繪制在目的地的時(shí)候圖片被轉(zhuǎn)換。同樣的,路徑繪制例程接受一些參數(shù),這些參數(shù)指定了一個(gè)圓弧在默認(rèn)的坐標(biāo)系統(tǒng)是順時(shí)針還是逆時(shí)針。假如一個(gè)坐標(biāo)系統(tǒng)被修改,他的結(jié)果也被修改,就像一個(gè)圖片反射在鏡子里。圖1-5,傳遞相同的參數(shù),一個(gè)是逆時(shí)針默認(rèn)的坐標(biāo)系,一個(gè)是順時(shí)針的轉(zhuǎn)換后的坐標(biāo)系。

?????? 它是取決于你的應(yīng)用程序來調(diào)整Quartz調(diào)用上下文,這些上下文已經(jīng)做了調(diào)整。例如,如果 你想要一個(gè)圖形或者PDF畫出準(zhǔn)確的上下文,您的應(yīng)用程序也許需要臨時(shí)調(diào)整圖形上下文的CTM(當(dāng)前矩陣轉(zhuǎn)換)。在iOS中,你使用圖片對(duì)象包裹你創(chuàng)建的CGImage對(duì)象,你不需要修改CTM,通過UIKit框架,圖片對(duì)象會(huì)自動(dòng)為即將修改的坐標(biāo)系統(tǒng)補(bǔ)償。
???? Important:在你計(jì)劃直接利用Quartz在iOS 上寫程序的時(shí)候以上討論是很容易理解的,但這遠(yuǎn)遠(yuǎn)不夠,在iOS 3.2以后當(dāng)你創(chuàng)建上下文的時(shí)候,還是有額外的變化要去匹配UIKit默認(rèn)的慣例。尤其是,模式和陰影,它們并不被CTM影響,需要單獨(dú)調(diào)整來匹配UIKit的坐標(biāo)系統(tǒng)。這種情況下,CTM就沒有等效的機(jī)制使你用Quartz創(chuàng)建的上下文能夠匹配操作UIKit的行為。你的應(yīng)用程序必須認(rèn)識(shí)到哪一種被繪制的上下文需要調(diào)整從而達(dá)到符合上下文的期望。
Memory Management: Object Ownership? 內(nèi)存管理對(duì)象所有權(quán)
Quar采用引用計(jì)數(shù)管理內(nèi)存。創(chuàng)建時(shí),引用計(jì)數(shù)為1,可以通過調(diào)用函數(shù)來增加引用計(jì)數(shù),以及通過調(diào)用函數(shù)來釋放引用計(jì)數(shù)來釋放對(duì)象。當(dāng)引用計(jì)數(shù)減為0,對(duì)象被釋放。該模型允許對(duì)象安全地共享對(duì)其他對(duì)象的引用。
有幾個(gè)簡(jiǎn)單的規(guī)則要記?。?/p>
???? 1° : 創(chuàng)建或者拷貝對(duì)象,當(dāng)你使用完后必須釋放掉,否則會(huì)造成內(nèi)存泄漏。
? ? 2°: 假如你不曾擁有一個(gè)對(duì)象,可是想持有他的屬性。你必須retain 和release它在使用完之后。在Quartz中有指定的方法去持有一個(gè)對(duì)象和釋放一個(gè)對(duì)象。比如,當(dāng)你引用了一個(gè)CGColorspace對(duì)象,你需要使用CGColorSpaceRetain and CGColorSpaceRelease持有它,并且在需要的時(shí)候釋放掉。你也可以用Core Foundation 的方法: CFRetain and CFRelease。但是你一定要特別小心不要傳遞NULL給這些方法。