Quartz 2D編程指南是論壇會員德魯伊翻譯的國外的Quartz 2D一系列學習資料眉撵,供大家參考棋傍。
Quartz 2D是一個二維圖形繪制引擎殷费,支持iOS環(huán)境和Mac OS X環(huán)境勇婴。我們可以使用Quartz 2D API來實現(xiàn)許多功能蒙幻,如基本路徑的繪制、透明度衣迷、描影畏鼓、繪制陰影、透明層壶谒、顏色管理云矫、反鋸齒、PDF文檔生成和PDF元數(shù)據(jù)訪問汗菜。
在需要的時候让禀,Quartz 2D還可以借助圖形硬件的功能。
在Mac OS X中陨界,Quartz 2D可以與其它圖形圖像技術(shù)混合使用巡揍,如Core Image、Core Video菌瘪、OpenGL腮敌、QuickTime。例如俏扩,通過使用 QuickTime的GraphicsImportCreateCGImage函數(shù)糜工,可以用 Quartz從一個 QuickTime圖形導入器中創(chuàng)建一個圖像。
Page
Quartz 2D在圖像中使用了繪畫者模型(painter’s model)动猬。在繪畫者模型中啤斗,每個連續(xù)的繪制操作都是將一個繪制層(a layer of ‘paint’)放置于一個畫布(‘canvas’),我們通常稱這個畫布為(Page)赁咙。 Page上的繪圖可以通過額外的繪制操作來疊加更多的繪圖钮莲。Page上的圖形對象只能通過疊加更多的繪圖來改變。這個模型允許我們使用小的圖元來構(gòu)建復雜的圖形彼水。
圖1-1展示了繪畫者模型如何工作崔拥。從圖中可以看出不同的繪制順序所產(chǎn)生的效果不一樣。
Page可以是一張紙(如果輸出設(shè)備是打印機)凤覆,也可以是虛擬的紙張(如果輸出設(shè)備是PDF文件)链瓦,還可以是bitmap圖像。這根據(jù)實際使用的graphics context而定盯桦。
繪制目標:Graphics Context
Graphics Context是一個數(shù)據(jù)類型(CGContextRef)慈俯,用于封裝Quartz繪制圖像到輸出設(shè)備的信息(①eg.?CGContextRef將根據(jù)繪圖路徑繪制的圖形和Layer聯(lián)系起來)。設(shè)備可以是PDF文件拥峦、bitmap或者顯示器的窗口上贴膘。Graphics Context中的信息包括在Page中的圖像的圖形繪制參數(shù)和設(shè)備相關(guān)的表現(xiàn)形式。Quartz中所有的對象都是繪制到一個Graphics Context中略号。
我們可以將Graphics Context想像成繪制目標刑峡,如圖1-2所示洋闽。當用Quartz繪圖時,所有設(shè)備相關(guān)的特性都包含在我們所使用的Graphics Context中突梦。換句話說诫舅,我們可以簡單地給Quartz繪圖序列指定不同的Graphics Context,就可將相同的圖像繪制到不同的設(shè)備上宫患。我們不需要任何設(shè)備相關(guān)的計算刊懈;這些都由Quartz替我們完成。
Quartz提供了以下幾種類型的Graphics Context娃闲,詳細的介紹將在后續(xù)章節(jié)說明俏讹。
Bitmap Graphics Context
PDF Graphics Context
Window Graphics Context
Layer Context
Post Graphics Context
Quartz 2D 數(shù)據(jù)類型
除了 Graphics Context 之外,Quartz 2D API還定義一些數(shù)據(jù)類型畜吊。由于這些API就Core Graphics框架的一部分泽疆,所以這些數(shù)據(jù)類型都是以CG開頭的。
Quartz 2D使用這些數(shù)據(jù)類型來創(chuàng)建對象玲献,通過操作這些對象來獲取特定的圖形殉疼。圖1-3例舉了三個使用Quartz 2D的繪制操作所獲得的圖像。
下面列出了Quartz 2D包含的數(shù)據(jù)類型:
CGPathRef:用于向量圖捌年,可創(chuàng)建路徑瓢娜,并進行填充或描畫(stroke)
CGImageRef:用于表示bitmap圖像和基于采樣數(shù)據(jù)的bitmap圖像遮罩。
CGLayerRef:用于表示可用于重復繪制(如背景)和幕后(offscreen)繪制的繪畫層
CGPatternRef:用于重繪圖
CGShadingRef礼预、CGGradientRef:用于繪制漸變
CGFunctionRef:用于定義回調(diào)函數(shù)眠砾,該函數(shù)包含一個隨機的浮點值參數(shù)。當為陰影創(chuàng)建漸變時使用該類型
CGColorRef, CGColorSpaceRef:用于告訴Quartz如何解釋顏色
CGImageSourceRef,CGImageDestinationRef:用于在Quartz中移入移出數(shù)據(jù)
CGFontRef:用于繪制文本
CGPDFDictionaryRef, CGPDFObjectRef, CGPDFPageRef, CGPDFStream, CGPDFStringRef, and CGPDFArrayRef:用于訪問PDF的元數(shù)據(jù)
CGPDFScannerRef, CGPDFContentStreamRef:用于解析PDF元數(shù)據(jù)
CGPSConverterRef:用于將PostScript轉(zhuǎn)化成PDF托酸。在iOS中不能使用褒颈。
圖形狀態(tài)
Quartz通過修改當前圖形狀態(tài)(current graphics state)來修改繪制操作的結(jié)果。圖形狀態(tài)包含用于繪制程序的參數(shù)励堡。繪制程序根據(jù)這些繪圖狀態(tài)來決定如何渲染結(jié)果谷丸。例如,當你調(diào)用設(shè)置填充顏色的函數(shù)時应结,你將改變存儲在當前繪圖狀態(tài)中的顏色值刨疼。
Graphics Context包含一個繪圖狀態(tài)棧。當Quartz創(chuàng)建一個Graphics Context時鹅龄,棧為空揩慕。當保存圖形狀態(tài)時,Quartz將當前圖形狀態(tài)的一個副本壓入棧中扮休。當還原圖形狀態(tài)時迎卤,Quartz將棧頂?shù)膱D形狀態(tài)出棧。出棧的狀態(tài)成為當前圖形狀態(tài)肛炮。
可使用函數(shù)CGContextSaveGState來保存圖形狀態(tài)止吐,CGContextRestoreGState來還原圖形狀態(tài)。
注意:并不是當前繪制環(huán)境的所有方面都是圖形狀態(tài)的元素侨糟。如碍扔,圖形狀態(tài)不包含當前路徑(current path)。下面列出了圖形狀態(tài)相關(guān)的參數(shù):
Current transformation matrix (CTM):當前轉(zhuǎn)換矩陣
Clipping area:裁剪區(qū)域
Line: 線
Accuracy of curve estimation (flatness):曲線平滑度
Anti-aliasing setting:反鋸齒設(shè)置
Color: 顏色
Alpha value (transparency):透明度
Rendering intent:渲染目標
Color space: 顏色空間
Text: 文本
Blend mode:混合模式
Quartz 2D 坐標系統(tǒng)
坐標系統(tǒng)定義是被繪制到Page上的對象的位置及大小范圍秕重,如圖1-4所示不同。我們在用戶空間坐標系統(tǒng)(user-space coordination system,簡稱用戶空間)中指定圖形的位置及大小溶耘。坐標值是用浮點數(shù)來定義的二拐。
由于不同的設(shè)備有不同的圖形功能,所以圖像的位置及大小依賴于設(shè)備凳兵。例如百新,一個顯示設(shè)備可能每英寸只能顯示少于96個像素,而打印機可能每英寸能顯示300個像素庐扫。如果在設(shè)備級別上定義坐標系統(tǒng)饭望,則在一個設(shè)備上繪制的圖形無法在其它設(shè)備上正常顯示。
Quartz通過使用當前轉(zhuǎn)換矩陣(current transformation matrix形庭, CTM)將一個獨立的坐標系統(tǒng)(user space)映射到輸出設(shè)備的坐標系統(tǒng)(device space)铅辞,以此來解決設(shè)備依賴問題。 CTM是一種特殊類型的矩陣(affine transform, 仿射矩陣)萨醒,通過平移(translation)斟珊、旋轉(zhuǎn)(rotation)、縮放(scale)操作將點從一個坐標空間映射到另外一個坐標空間富纸。
CTM還有另外一個目的:允許你通過轉(zhuǎn)換來決定對象如何被繪制囤踩。例如,為了繪制一個旋轉(zhuǎn)了45度的盒子晓褪,我們可以在繪制盒子之前旋轉(zhuǎn)Page的坐標系統(tǒng)高职。Quartz使用旋轉(zhuǎn)過的坐標系統(tǒng)來將盒子繪制到輸出設(shè)備中。
用戶空間的點用坐標對(x, y)來表示辞州,(0, 0)表示坐標原點怔锌。Quartz中默認的坐標系統(tǒng)是:沿著x軸從左到右坐標值逐漸增大;沿著y軸從下到上坐標值逐漸增大变过。
有一些技術(shù)在設(shè)置它們的graphics context時使用了不同于Quartz的默認坐標系統(tǒng)埃元。相對于Quartz來說,這些坐標系統(tǒng)是修改的坐標系統(tǒng)(modified coordinate system)媚狰,當在這些坐標系統(tǒng)中顯示Quartz繪制的圖形時岛杀,必須進行轉(zhuǎn)換。最常見的一種修改的坐標系統(tǒng)是原點位于左上角崭孤,而沿著y軸從上到下坐標值逐漸增大类嗤。我們可以在如下一些地方見到這種坐標系統(tǒng):
在Mac OS X中糊肠,重寫過isFlipped方法以返回yes的NSView類的子類
在IOS中,由UIView返回的繪圖上下文
在IOS中遗锣,通過調(diào)用UIGraphicsBeginImageContextWithOptions函數(shù)返回的繪圖上下文
如果應(yīng)用程序想以相同的繪制程序在一個UIView對象和PDF Graphics Context上進行繪制货裹,需要做一個變換以使PDF Graphics Context使用與UIView相同的坐標系。要達到這一目的精偿,只需要對PDF的上下文的原點做一個平移(移到左上角)和用-1對y坐標值進行縮放弧圆。圖1-5顯示了這種變換操作:
我們的應(yīng)用程序負責調(diào)整Quartz調(diào)用以確保有一個轉(zhuǎn)換應(yīng)用到上下文中。例如笔咽,如果你想要一個圖片或PDF正確的繪制到一個Graphics Context中搔预,你的應(yīng)用程序可能需要臨時調(diào)整Graphics Context的CTM。在IOS中叶组,如果使用UIImage對象來包裹創(chuàng)建的CGImage對象拯田,可以不需要修改CTM。UIImage將自動進行補償以適用UIKit的坐標系統(tǒng)甩十。
復制代碼重要:如果你打算在IOS上開發(fā)與Quartz相關(guān)的程序勿锅,了解以上所討論的是很有用的,但不是必須的枣氧。在IOS 3.2及后續(xù)的版本中溢十,當UIKit為你的應(yīng)用程序創(chuàng)建一個繪圖上下文時,也對上下文進行了額外的修改以匹配UIKit的約定达吞。特別的张弛,patterns和shadows(不被CTM影響)單獨進行調(diào)整以匹配UIKit坐標系統(tǒng)。在這種情況下酪劫,沒有一個等價的機制讓CTM來轉(zhuǎn)換Quartz和UIKit的上下文吞鸭。我們必須認識到在什么樣的上下文中進行繪制,并調(diào)整行為以匹配上下文的預期覆糟。
內(nèi)存管理:對象所有權(quán)
uartz使用Core Foundation內(nèi)存管理模型(引用計數(shù))刻剥。所以,對象的創(chuàng)建與銷毀與通常的方式是一樣的滩字。在Quartz中造虏,需要記住如下一些規(guī)則:
如果創(chuàng)建或拷貝一個對象,你將擁有它麦箍,因此你必須釋放它漓藕。通常,如果使用含有”Create”或“Copy”單詞的函數(shù)獲取一個對象挟裂,當使用完后必須釋放享钞,否則將導致內(nèi)存泄露。
如果使用不含有”Create”或“Copy”單詞的函數(shù)獲取一個對象诀蓉,你將不會擁有對象的引用栗竖,不需要釋放它暑脆。
如果你不擁有一個對象而打算保持它,則必須retain它并且在不需要時release掉狐肢√砺穑可以使用Quartz 2D的函數(shù)來指定retain和release一個對象。例如处坪,如果創(chuàng)建了一個CGColorspace對象,則使用函數(shù)CGColorSpaceRetain和CGColorSpaceRelease來retain和release對象架专。同樣同窘,可以使用Core Foundation的CFRetain和CFRelease,但是注意不能傳遞NULL值給這些函數(shù)部脚。