Quartz 2D編程指南(1) - 概覽

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ù)部脚。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末想邦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子委刘,更是在濱河造成了極大的恐慌丧没,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锡移,死亡現(xiàn)場離奇詭異呕童,居然都是意外死亡,警方通過查閱死者的電腦和手機淆珊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門夺饲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人施符,你說我怎么就攤上這事往声。” “怎么了戳吝?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵浩销,是天一觀的道長。 經(jīng)常有香客問我听哭,道長慢洋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任陆盘,我火速辦了婚禮且警,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘礁遣。我一直安慰自己斑芜,他們只是感情好,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布祟霍。 她就那樣靜靜地躺著杏头,像睡著了一般盈包。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上醇王,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天呢燥,我揣著相機與錄音,去河邊找鬼寓娩。 笑死叛氨,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的棘伴。 我是一名探鬼主播寞埠,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼焊夸!你這毒婦竟也來了仁连?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤阱穗,失蹤者是張志新(化名)和其女友劉穎饭冬,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體揪阶,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡昌抠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鲁僚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扰魂。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蕴茴,靈堂內(nèi)的尸體忽然破棺而出劝评,到底是詐尸還是另有隱情,我是刑警寧澤倦淀,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布蒋畜,位于F島的核電站,受9級特大地震影響撞叽,放射性物質(zhì)發(fā)生泄漏姻成。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一愿棋、第九天 我趴在偏房一處隱蔽的房頂上張望科展。 院中可真熱鬧,春花似錦糠雨、人聲如沸才睹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽琅攘。三九已至垮庐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間坞琴,已是汗流浹背哨查。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留剧辐,地道東北人寒亥。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像荧关,于是被迫代替她去往敵國和親溉奕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容