Quartz 2D編程指南 (二) —— Quartz 2D概覽(二)

版本記錄

版本號 時間
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函數GraphicsImportCreateCGImageQuickTime圖形導入器在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 AnimationOpenGL ESUIKit類。


The Page - 頁面

Quartz 2D使用painter’s model進行成像。 在painter’s model中,每個連續的繪圖操作都將一層“paint”應用于輸出畫布(canvas),通常稱為page。 可以通過在其他繪圖操作中覆蓋更多繪制來修改頁面上的繪制。 除非覆蓋更多顏料,否則無法修改頁面上繪制的對象。 此模型允許您從少量強大的基元構造極其復雜的圖像。

圖1-1顯示了painter’s model的工作原理。 要在圖的頂部獲取圖像,首先繪制左側的形狀,然后繪制實心形狀。 實心形狀覆蓋第一個形狀,遮擋除第一個形狀的周邊之外的所有形狀。 形狀在圖的底部以相反的順序繪制,首先繪制實心形狀。 如您所見,在painter’s model中,繪制順序很重要。

Figure 1-1 The painter’s model

page可以是真正的紙張(如果輸出設備是打印機); 它可能是一張虛擬紙(如果輸出設備是PDF文件); 它甚至可能是位圖圖像。 page的確切性質取決于您使用的特定圖形上下文。


Drawing Destinations: The Graphics Context - 繪制目的地:上下文

graphics context是一種不透明的數據類型(CGContextRef),它封裝了Quartz用于將圖像繪制到輸出設備的信息,例如PDF文件,位圖或顯示器上的窗口。 圖形上下文中的信息包括圖形繪制參數和page上繪制的設備特定表示。 Quartz中的所有對象都被繪制或者被包含到圖形上下文。

您可以將圖形上下文視為繪圖目標,如圖1-2所示。 使用Quartz繪制時,所有特定于設備的特征都包含在您使用的特定類型的圖形上下文中。 換句話說,您可以通過為相同的Quartz繪圖例程序列提供不同的圖形上下文,將相同的圖像繪制到不同的設備。 您無需執行任何特定于設備的計算,Quartz為您做到了。

Figure 1-2 Quartz drawing destinations

這些圖形上下文可供您的應用程序使用:

  • 位圖圖形上下文(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將著色用作填充顏色。
Figure 1-3 Opaque data types are the basis of drawing primitives in Quartz 2D

Quartz 2D中提供的不透明數據類型包括以下內容:


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所示)定義了用于表示要在頁面上繪制的對象的位置和大小的位置范圍。 您可以在用戶空間坐標系中指定圖形的位置和大小,或者更簡單地說,指定用戶空間。 坐標定義為浮點值。

Figure 1-4 The Quartz coordinate system

由于不同的設備具有不同的底層成像功能,因此必須以與設備無關的方式定義圖形的位置和大小。例如,屏幕顯示設備可能能夠顯示每英寸不超過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軸更改為指向頁面底部。您可能會看到使用此特定坐標系的幾個地方如下:

UIKit返回帶有修改坐標系的Quartz繪圖上下文的原因是UIKit使用不同的默認坐標約定;它將變換應用于它創建的Quartz上下文,以便它們匹配其約定。如果您的應用程序想要使用相同的繪圖例程來繪制UIView對象和PDF圖形上下文(由Quartz創建并使用默認坐標系),則需要應用變換以便PDF圖形上下文接收相同的修改坐標系(modified coordinate system)。要執行此操作,請應用將原點轉換為PDF上下文左上角的變換,并將y坐標縮放-1。

使用縮放變換來讓y坐標為負值會改變Quartz繪圖中的一些約定。例如,如果調用CGContextDrawImage將圖像繪制到上下文中,則在將圖像繪制到目標時,圖像將被變換修改。類似地,路徑繪制例程接受指定是否在默認坐標系中以順時針或逆時針方向繪制弧的參數。如果修改了坐標系,則也會修改結果,就像圖像在鏡像中顯示一樣。在圖1-5中,將相同的參數傳遞給Quartz會導致默認坐標系中的順時針圓弧和y坐標被變換抵消后的逆時針圓弧。

Figure 1-5 Modifying the coordinate system creates a mirrored image

您的應用程序可以調整它對已應用轉換的上下文進行的任何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時,將釋放該對象。此模型允許對象安全地共享對其他對象的引用。

要記住一些簡單的規則:

  • 如果您創建或復制對象,則擁有它,因此您必須將其釋放。也就是說,通常,如果從名稱中使用CreateCopy字樣的函數獲取對象,則必須在完成后釋放該對象。否則,會導致內存泄漏。
  • 如果從名稱中不包含CreateCopy字樣的函數中獲取對象,則不具有對該對象的引用,并且不得釋放該對象。該對象將在未來的某個時刻由其所有者發布。
  • 如果您沒有擁有對象并且需要保留它,則必須引用它并在完成后將其釋放。您可以使用特定于對象的Quartz 2D函數來保留和釋放該對象。例如,如果您收到對CGColorspace對象的引用,則使用CGColorSpaceRetainCGColorSpaceRelease函數根據需要保留和釋放對象。您還可以使用Core Foundation函數CFRetainCFRelease,但必須注意不要將NULL傳遞給這些函數。

后記

本篇主要講述了Quartz 2D概覽,感興趣的給個贊或者關注~~~

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,967評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,273評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,870評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,742評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,527評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,010評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,250評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,769評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,656評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,853評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,103評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,472評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,717評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,487評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,815評論 2 372

推薦閱讀更多精彩內容