版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2018.09.03 |
前言
Quartz 2D
框架相信大家都知道,也都一直在使用。Quartz 2D
的API是純C語言的,它是一個二維繪圖引擎,同時支持iOS和Mac系統。Quartz 2D
的API來自于Core Graphics
框架,數據類型和函數基本都以CG作為前綴,接下來幾篇我們就一起來看一下這個框架。感興趣可以看上面幾篇文章。
1. Quartz 2D編程指南 (一) —— 簡介(一)
Overview of 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, and QuickTime
。可以使用QuickTime
函數GraphicsImportCreateCGImage從QuickTime
圖形導入器在Quartz中創建圖像。有關詳細信息,請參閱QuickTime Framework Reference
。在Mac OS X中在Moving Data Between Quartz 2D and Core Image in Mac OS X描述了如何向Core Image
提供圖像,Core Image
是一個支持圖像處理的框架。
同樣,在iOS中,Quartz 2D
可與所有可用的圖形和動畫技術配合使用,例如Core Animation
,OpenGL ES
和UIKit
類。
The Page - 頁面
Quartz 2D
使用painter’s model
進行成像。 在painter’s model
中,每個連續的繪圖操作都將一層“paint”
應用于輸出畫布(canvas),通常稱為page
。 可以通過在其他繪圖操作中覆蓋更多繪制來修改頁面上的繪制。 除非覆蓋更多顏料,否則無法修改頁面上繪制的對象。 此模型允許您從少量強大的基元構造極其復雜的圖像。
圖1-1顯示了painter’s model
的工作原理。 要在圖的頂部獲取圖像,首先繪制左側的形狀,然后繪制實心形狀。 實心形狀覆蓋第一個形狀,遮擋除第一個形狀的周邊之外的所有形狀。 形狀在圖的底部以相反的順序繪制,首先繪制實心形狀。 如您所見,在painter’s model
中,繪制順序很重要。
page
可以是真正的紙張(如果輸出設備是打印機); 它可能是一張虛擬紙(如果輸出設備是PDF文件); 它甚至可能是位圖圖像。 page
的確切性質取決于您使用的特定圖形上下文。
Drawing Destinations: The Graphics Context - 繪制目的地:上下文
graphics context
是一種不透明的數據類型(CGContextRef),它封裝了Quartz用于將圖像繪制到輸出設備的信息,例如PDF文件,位圖或顯示器上的窗口。 圖形上下文中的信息包括圖形繪制參數和page
上繪制的設備特定表示。 Quartz中的所有對象都被繪制或者被包含到圖形上下文。
您可以將圖形上下文視為繪圖目標,如圖1-2所示。 使用Quartz繪制時,所有特定于設備的特征都包含在您使用的特定類型的圖形上下文中。 換句話說,您可以通過為相同的Quartz繪圖例程序列提供不同的圖形上下文,將相同的圖像繪制到不同的設備。 您無需執行任何特定于設備的計算,Quartz為您做到了。
這些圖形上下文可供您的應用程序使用:
- 位圖圖形上下文
(bitmap graphics context)
允許您將RGB顏色,CMYK顏色或灰度繪制到位圖中。位圖(bitmap
)是像素的矩形陣列(或光柵),每個像素表示圖像中的一個點。位圖圖像也稱為采樣圖像(sampled images)
。請參閱Creating a Bitmap Graphics Context。 - PDF圖形上下文
(PDF graphics context)
允許您創建PDF文件。在PDF文件中,您的繪圖將保留為一系列命令。 PDF文件和位圖之間存在一些顯著差異:- 與位圖不同,PDF文件可能包含多個頁面。
- 當您從另一臺設備上的PDF文件中繪制頁面時,生成的圖像會針對該設備的顯示特性進行優化。
- PDF文件本質上是分辨率無關的 - 繪制它們的大小可以無限增加或減少,而不會犧牲圖像細節。用戶感知的位圖圖像質量與要查看位圖的分辨率相關聯。
請參閱Creating a PDF Graphics Context。
- 窗口圖形上下文
(window graphics context)
是可用于繪制到窗口中的圖形上下文。請注意,由于Quartz 2D是圖形引擎而不是窗口管理系統,因此您可以使用其中一個應用程序框架來獲取窗口的圖形上下文。有關詳細信息,請參閱 Creating a Window Graphics Context in Mac OS X。 - 圖層上下文
(layer context)
(CGLayerRef)是與另一個圖形上下文關聯的屏幕外繪圖目標。它旨在將圖層繪制到創建它的圖形上下文時獲得最佳性能。與位圖圖形上下文相比,圖層上下文可以是屏幕外繪制的更好選擇。請參閱Core Graphics Layer Drawing。 - 如果要在Mac OS X中進行打印,可以將內容發送到由打印框架管理的PostScript圖形上下文
(PostScript graphics context)
。有關詳細信息,請參閱Obtaining a Graphics Context for Printing。
Quartz 2D Opaque Data Types - Quartz 2D不透明數據類型
除了圖形上下文之外,Quartz 2D API
還定義了各種不透明數據類型。由于API是Core Graphics
框架的一部分,因此數據類型和對其進行操作的例程使用CG
前綴。
Quartz 2D
根據應用程序操作的不透明數據類型創建對象,以實現特定的繪圖輸出。圖1-3顯示了將繪圖操作應用于Quartz 2D提供的三個對象時可以實現的各種結果。例如:
- 您可以通過創建PDF頁面對象,將旋轉操作應用于圖形上下文,并要求Quartz 2D將頁面繪制到圖形上下文來旋轉和顯示PDF頁面。
- 您可以通過創建圖案
(pattern)
對象,定義構成圖案的形狀以及設置Quartz 2D以在繪制圖形上下文時將圖案用作繪圖來繪制圖案。 - 您可以通過創建著色對象來填充具有軸向或徑向著色的區域,提供確定著色中每個點的顏色的函數,然后要求
Quartz 2D
將著色用作填充顏色。
Quartz 2D
中提供的不透明數據類型包括以下內容:
- CGPathRef,用于矢量圖形以創建您填充或描邊的路徑。見Paths。
- CGImageRef,用于根據您提供的樣本數據表示位圖圖像和位圖圖像蒙版。請參見 Bitmap Images and Image Masks。
- CGLayerRef,用于表示可用于重復繪圖(例如背景或圖案)和屏幕外繪圖的繪圖層。請參閱Core Graphics Layer Drawing
- CGPatternRef,用于重復繪圖。見Patterns。
- CGShadingRef和CGGradientRef,用于繪制漸變。請參閱Gradients。
- CGFunctionRef,用于定義帶有任意數量浮點參數的回調函數。在為著色創建漸變時使用此數據類型。請參閱Gradients。
- CGColorRef和CGColorSpaceRef,用于告知Quartz如何解釋顏色。請參閱Color and Color Spaces。
- CGImageSourceRef和CGImageDestinationRef,用于將數據移入和移出Quartz。請參閱Data Management in Quartz 2D和mage I/O Programming Guide。
- CGFontRef,用于繪制文本。見Text。
- CGPDFDictionaryRef, CGPDFObjectRef, CGPDFPageRef, CGPDFStream, CGPDFStringRef和CGPDFArrayRef,它們提供對PDF元數據的訪問。請參閱PDF Document Creation, Viewing, and Transforming。
- CGPDFScannerRef和CGPDFContentStreamRef,用于解析PDF元數據。請參閱PDF Document Parsing。
-
CGPSConverterRef,用于將
PostScript
轉換為PDF
。它在iOS中不可用。請參閱PostScript Conversion。
Graphics States - 圖形狀態
Quartz根據當前圖形狀態(current graphics state)
中的參數修改繪制操作的結果。圖形狀態包含參數,這些參數將作為繪圖例程的參數。繪制到圖形上下文的例程會查詢圖形狀態以確定如何呈現其結果。例如,當您調用函數來設置填充顏色時,您正在修改存儲在當前圖形狀態中的值。當前圖形狀態的其他常用元素包括線寬,當前位置和文本字體大小。
圖形上下文包含一堆圖形狀態。當Quartz創建圖形上下文時,堆棧為空。保存圖形狀態時,Quartz會將當前圖形狀態的副本推送到堆棧中。當您恢復圖形狀態時,Quartz會將圖形狀態從堆棧頂部彈出。彈出狀態變為當前圖形狀態。
要保存當前圖形狀態,請使用函數CGContextSaveGState
將當前圖形狀態的副本推送到堆棧。要恢復以前保存的圖形狀態,請使用函數CGContextRestoreGState
將當前圖形狀態替換為堆棧頂部的圖形狀態。
請注意,并非當前繪圖環境的所有方面都是圖形狀態的元素。例如,當前路徑不被視為圖形狀態的一部分,因此在調用函數CGContextSaveGState
時不會保存。表1-1列出了調用此函數時保存的圖形狀態參數。
Table 1-1 Parameters that are associated with the graphics state
Parameters | Discussed in this chapter |
---|---|
Current transformation matrix (CTM) | Transforms |
Clipping area | Paths |
Line: width, join, cap, dash, miter limit | Paths |
Accuracy of curve estimation (flatness) | Paths |
Anti-aliasing setting | Graphics Contexts |
Color: fill and stroke settings | Color and Color Spaces |
Alpha value (transparency) | Color and Color Spaces |
Rendering intent | Color and Color Spaces |
Color space: fill and stroke settings | Color and Color Spaces |
Text: font, font size, character spacing, text drawing mode | Text |
Blend mode | Paths and Bitmap Images and Image Masks |
Quartz 2D Coordinate Systems - Quartz 2D坐標系統
坐標系統(如圖1-4所示)定義了用于表示要在頁面上繪制的對象的位置和大小的位置范圍。 您可以在用戶空間坐標系中指定圖形的位置和大小,或者更簡單地說,指定用戶空間。 坐標定義為浮點值。
由于不同的設備具有不同的底層成像功能,因此必須以與設備無關的方式定義圖形的位置和大小。例如,屏幕顯示設備可能能夠顯示每英寸不超過96個像素,而打印機可能能夠顯示每英寸300個像素。如果在設備級別定義坐標系(在此示例中為96像素或300像素),則在該空間中繪制的對象無法在沒有可見失真的其他設備上再現。它們看起來太大或太小。
Quartz通過單獨的坐標系統 - 用戶空間(user space)
- 使用當前變換矩陣(current transformation matrix)
或CTM將其映射到輸出設備 - 設備空間(device space)
的坐標系來實現設備獨立性。矩陣是用于有效地描述一組相關方程的數學構造。當前變換矩陣是稱為仿射變換的特定類型的矩陣,其通過應用平移,旋轉和縮放操作(移動,旋轉和調整坐標系的大小的計算)將點從一個坐標空間映射到另一個坐標空間。
當前轉換矩陣具有次要目的:它允許您轉換對象的繪制方式。例如,要繪制旋轉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圖形上下文接收相同的修改坐標系(modified coordinate system)
。要執行此操作,請應用將原點轉換為PDF上下文左上角的變換,并將y坐標縮放-1。
使用縮放變換來讓y坐標為負值會改變Quartz繪圖中的一些約定。例如,如果調用CGContextDrawImage將圖像繪制到上下文中,則在將圖像繪制到目標時,圖像將被變換修改。類似地,路徑繪制例程接受指定是否在默認坐標系中以順時針或逆時針方向繪制弧的參數。如果修改了坐標系,則也會修改結果,就像圖像在鏡像中顯示一樣。在圖1-5中,將相同的參數傳遞給Quartz會導致默認坐標系中的順時針圓弧和y坐標被變換抵消后的逆時針圓弧。
您的應用程序可以調整它對已應用轉換的上下文進行的任何Quartz調用。例如,如果要將圖像或PDF正確繪制到圖形上下文中,則應用程序可能需要臨時調整圖形上下文的CTM。在iOS中,如果使用UIImage
對象來包裝您創建的CGImage
對象,則無需修改CTM。 UIImage
對象自動補償UIKit應用的修改坐標系。
重要提示:上述討論對于了解您是否計劃在iOS上編寫直接針對Quartz的應用程序至關重要,但這還不夠。在iOS 3.2及更高版本中,當UIKit為您的應用程序創建繪圖上下文時,它還會對上下文進行其他更改以匹配默認的UIKIt約定。特別是,不受CTM影響的圖案和陰影會單獨調整,以使其慣例與UIKit的坐標系相匹配。在這種情況下,沒有與CTM等效的機制,您的應用程序可以使用它來更改Quartz創建的上下文以匹配UIKit提供的上下文的行為;您的應用程序必須識別它正在繪制的上下文類型并調整其行為以匹配上下文的期望。
Memory Management: Object Ownership - 內存管理:對象所有權
Quartz
使用Core Foundation
內存管理模型,其中對象被引用計數。創建時,Core Foundation對象的引用計數為1。您可以通過調用引用對象的函數來增加引用計數,并通過調用函數來減少引用計數以釋放對象。當引用計數遞減到0時,將釋放該對象。此模型允許對象安全地共享對其他對象的引用。
要記住一些簡單的規則:
- 如果您創建或復制對象,則擁有它,因此您必須將其釋放。也就是說,通常,如果從名稱中使用
Create
或Copy
字樣的函數獲取對象,則必須在完成后釋放該對象。否則,會導致內存泄漏。 - 如果從名稱中不包含
Create
或Copy
字樣的函數中獲取對象,則不具有對該對象的引用,并且不得釋放該對象。該對象將在未來的某個時刻由其所有者發布。 - 如果您沒有擁有對象并且需要保留它,則必須引用它并在完成后將其釋放。您可以使用特定于對象的Quartz 2D函數來保留和釋放該對象。例如,如果您收到對
CGColorspace
對象的引用,則使用CGColorSpaceRetain
和CGColorSpaceRelease
函數根據需要保留和釋放對象。您還可以使用Core Foundation
函數CFRetain
和CFRelease
,但必須注意不要將NULL
傳遞給這些函數。
后記
本篇主要講述了Quartz 2D概覽,感興趣的給個贊或者關注~~~