標籤:des style blog http color os 使用 io 檔案
Quartz 2D編程指南是論壇會員德魯伊翻譯的國外的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圖形匯入器中建立一個映像。
Page
Quartz 2D在映像中使用了繪畫者模型(painter’s model)。在繪畫者模型中,每個連續的繪製操作都是將一個繪製層(a layer of ‘paint’)放置於一個畫布(‘canvas’),我們通常稱這個畫布為(Page)。 Page上的繪圖可以通過額外的繪製操作來疊加更多的繪圖。Page上的繪圖物件只能通過疊加更多的繪圖來改變。這個模型允許我們使用小的圖元來構建複雜的圖形。
圖1-1展示了繪畫者模型如何工作。可以看出不同的繪製順序所產生的效果不一樣。
Page可以是一張紙(如果輸出裝置是印表機),也可以是虛擬紙張(如果輸出裝置是PDF檔案),還可以是bitmap映像。這根據實際使用的graphics context而定。
繪製目標:Graphics Context
Graphics Context是一個資料類型(CGContextRef),用於封裝Quartz繪製映像到輸出裝置的資訊。裝置可以是PDF檔案、bitmap或者顯示器的視窗上。Graphics Context中的資訊包括在Page中的映像的圖形繪製參數和裝置相關的表現形式。Quartz中所有的對象都是繪製到一個Graphics Context中。
我們可以將Graphics Context想像成繪製目標,1-2所示。當用Quartz繪圖時,所有裝置相關的特性都包含在我們所使用的Graphics Context中。換句話說,我們可以簡單地給Quartz繪圖序列指定不同的Graphics Context,就可將相同的映像繪製到不同的裝置上。我們不需要任何裝置相關的計算;這些都由Quartz替我們完成。
Quartz提供了以下幾種類型的Graphics Context,詳細的介紹將在後續章節說明。
- Bitmap Graphics Context
- PDF Graphics Context
- Window Graphics Context
- Layer Context
- Post Graphics Context
Quartz 2D 資料類型
除了 Graphics Context 之外,Quartz 2D API還定義一些資料類型。由於這些API就Core Graphics架構的一部分,所以這些資料類型都是以CG開頭的。
Quartz 2D使用這些資料類型來建立對象,通過操作這些對象來擷取特定的圖形。圖1-3例舉了三個使用Quartz 2D的繪製操作所獲得的映像。
下面列出了Quartz 2D包含的資料類型:
- CGPathRef:用於向量圖,可建立路徑,並進行填充或描畫(stroke)
- CGImageRef:用於表示bitmap映像和基於採樣資料的bitmap映像遮罩。
- CGLayerRef:用於表示可用於重複繪製(如背景)和幕後(offscreen)繪製的繪畫層
- CGPatternRef:用於重繪圖
- CGShadingRef、CGGradientRef:用於繪製漸層
- CGFunctionRef:用於定義回呼函數,該函數包含一個隨機的浮點值參數。當為陰影建立漸層時使用該類型
- CGColorRef, CGColorSpaceRef:用於告訴Quartz如何解釋顏色
- CGImageSourceRef,CGImageDestinationRef:用於在Quartz中移入移出資料
- CGFontRef:用於繪製文本
- CGPDFDictionaryRef, CGPDFObjectRef, CGPDFPageRef, CGPDFStream, CGPDFStringRef, and CGPDFArrayRef:用於訪問PDF的中繼資料
- CGPDFScannerRef, CGPDFContentStreamRef:用於解析PDF中繼資料
- CGPSConverterRef:用於將PostScript轉化成PDF。在iOS中不能使用。
圖形狀態
Quartz通過修改當前圖形狀態(current graphics state)來修改繪製操作的結果。圖形狀態包含用於繪製程式的參數。繪製程式根據這些繪圖狀態來決定如何渲染結果。例如,當你調用設定填充顏色的函數時,你將改變儲存在當前繪圖狀態中的顏色值。
Graphics Context包含一個繪圖狀態棧。當Quartz建立一個Graphics Context時,棧為空白。當儲存圖形狀態時,Quartz將當前圖形狀態的一個副本壓入棧中。當還原圖形狀態時,Quartz將棧頂的圖形狀態出棧。出棧的狀態成為當前圖形狀態。
可使用函數CGContextSaveGState來儲存圖形狀態,CGContextRestoreGState來還原圖形狀態。
注意:並不是當前繪製環境的所有方面都是圖形狀態的元素。如,圖形狀態不包含當前路徑(current path)。下面列出了圖形狀態相關的參數:
- Current transformation matrix (CTM):當前轉換矩陣
- Clipping area:裁剪地區
- Line: 線
- Accuracy of curve estimation (flatness):曲線平滑度
- Anti-aliasing setting:反鋸齒設定
- Color: 顏色
- Alpha value (transparency):透明度
- Rendering intent:渲染目標
- Color space: 色彩空間
- Text: 文本
- Blend mode:混合模式
Quartz 2D 座標系統
座標系統定義是被繪製到Page上的對象的位置及大小範圍,1-4所示。我們在使用者空間座標系統(user-space coordination system,簡稱使用者空間)中指定圖形的位置及大小。座標值是用浮點數來定義的。
由於不同的裝置有不同的圖形功能,所以映像的位置及大小依賴於裝置。例如,一個顯示裝置可能每英寸只能顯示少於96個像素,而印表機可能每英寸能顯示300個像素。如果在裝置層級上定義座標系統,則在一個裝置上繪製的圖形無法在其它裝置上正常顯示。
Quartz通過使用當前轉換矩陣(current transformation matrix, CTM)將一個獨立的座標系統(user space)映射到輸出裝置的座標系統(device space),以此來解決裝置依賴問題。 CTM是一種特殊類型的矩陣(affine transform, 仿射矩陣),通過平移(translation)、旋轉(rotation)、縮放(scale)操作將點從一個座標空間映射到另外一個座標空間。
CTM還有另外一個目的:允許你通過轉換來決定對象如何被繪製。例如,為了繪製一個旋轉了45度的盒子,我們可以在繪製盒子之前旋轉Page的座標系統。Quartz使用旋轉過的座標系統來將盒子繪製到輸出裝置中。
使用者空間的點用座標組(x, y)來表示,(0, 0)表示座標原點。Quartz中預設的座標系統是:沿著x軸從左至右座標值逐漸增大;沿著y軸從下到上座標值逐漸增大。
有一些技術在設定它們的graphics context時使用了不同於Quartz的預設座標系統。相對於Quartz來說,這些座標系統是修改的座標系統(modified coordinate system),當在這些座標系統中顯示Quartz繪製的圖形時,必須進行轉換。最常見的一種修改的座標系統是原點位於左上方,而沿著y軸從上到下座標值逐漸增大。我們可以在如下一些地方見到這種座標系統:
- 在Mac OS X中,重寫過isFlipped方法以返回yes的NSView類的子類
- 在IOS中,由UIView返回的繪圖上下文
- 在IOS中,通過調用UIGraphicsBeginImageContextWithOptions函數返回的繪圖上下文
如果應用程式想以相同的繪製程式在一個UIView對象和PDF Graphics Context上進行繪製,需要做一個變換以使PDF Graphics Context使用與UIView相同的座標系。要達到這一目的,只需要對PDF的內容相關的原點做一個平移(移到左上方)和用-1對y座標值進行縮放。圖1-5顯示了這種變換操作:
我們的應用程式負責調整Quartz調用以確保有一個轉換應用到上下文中。例如,如果你想要一個圖片或PDF正確的繪製到一個Graphics Context中,你的應用程式可能需要臨時調整Graphics Context的CTM。在IOS中,如果使用UIImage對象來包裹建立的CGImage對象,可以不需要修改CTM。UIImage將自動進行補償以適用UIKit的座標系統。
複製代碼
- 重要:如果你打算在IOS上開發與Quartz相關的程式,瞭解以上所討論的是很有用的,但不是必須的。在IOS 3.2及後續的版本中,當UIKit為你的應用程式建立一個繪圖上下文時,也對上下文進行了額外的修改以匹配UIKit的約定。特別的,patterns和shadows(不被CTM影響)單獨進行調整以匹配UIKit座標系統。在這種情況下,沒有一個等價的機制讓CTM來轉換Quartz和UIKit的上下文。我們必須認識到在什麼樣的上下文中進行繪製,並調整行為以匹配內容相關的預期。
|
記憶體管理:對象所有權
Quartz使用Core Foundation記憶體管理模型(引用計數)。所以,對象的建立與銷毀與通常的方式是一樣的。在Quartz中,需要記住如下一些規則:
- 如果建立或拷貝一個對象,你將擁有它,因此你必須釋放它。通常,如果使用含有”Create”或“Copy”單詞的函數擷取一個對象,當使用完後必須釋放,否則將導致記憶體泄露。
- 如果使用不含有”Create”或“Copy”單詞的函數擷取一個對象,你將不會擁有對象的引用,不需要釋放它。
- 如果你不擁有一個對象而打算保持它,則必須retain它並且在不需要時release掉。可以使用Quartz 2D的函數來指定retain和release一個對象。例如,如果建立了一個CGColorspace對象,則使用函數CGColorSpaceRetain和CGColorSpaceRelease來retain和release對象。同樣,可以使用Core Foundation的CFRetain和CFRelease,但是注意不能傳遞NULL值給這些函數。
原帖地址:http://www.cocoachina.com/bbs/read.php?tid=77731&page=2
http://www.cocoachina.com/newbie/basic/2011/1111/3486.html
Quartz 2D編程指南(1) - 概覽