iOS開發(fā)(高級特性)——Quartz2D

What is Quartz2D

UIView及其子類的應(yīng)用目前比較熟悉了映挂,下面開始學(xué)習(xí)一下Quartz2D。我們從名字上來大致猜測一下這個東西是干嗎的期吓,2D好說應(yīng)該是說的2維和3D不同敲茄。那么Quartz又是個啥呢?Quartz的本意是石英石多柑,也有石英表的意思。在Java中有個叫Quartz的開源的作業(yè)調(diào)度框架楣责,估計是取其石英表的含義竣灌。但是在蘋果開發(fā)中,這個名字到底怎么解釋秆麸,還真猜不到初嘹。本來想望文知意的,結(jié)果不太靠譜沮趣,那我們直接先看一看蘋果對Quartz 2D的描述

Quartz 2D is an advanced, two-dimensional drawing engine available for iOS application development and to all Mac OS X application environments outside of the kernel. Quartz 2D provides low-level, lightweight 2D rendering with unmatched output fidelity regardless of display or printing device. Quartz 2D is resolution- and device-independent; you don’t need to think about the final destination when you use the Quartz 2D application programming interface (API) for drawing.

The Quartz 2D API is easy to use and provides access to powerful features such as transparency layers, path-based drawing, offscreen rendering, advanced color management, anti-aliased rendering, and PDF document creation, display, and parsing.

The Quartz 2D API is part of the Core Graphics framework, so you may see Quartz referred to as Core Graphics or, simply, CG

這么一大段話屯烦,我們找?guī)讉€關(guān)鍵字:drawing engine, resolution, device-independent, API。

這幾個關(guān)鍵詞加起來就是說房铭,我們可以調(diào)用Quartz 2D的接口來繪圖驻龟。至于后面的簡單易用,功能強大這一類的描述育叁,看看就好迅脐,不必較真芍殖。

我們已經(jīng)知道了Quartz2D是什么豪嗽,也知道它能干什么,接下來就是學(xué)習(xí)它是怎么做的豌骏。

When to use Quartz2D

討論怎么用之前龟梦,我們先了解一下什么時候用,即應(yīng)用場景窃躲。還是看蘋果給的東西吧计贰,畢竟這玩意都是他們搞出來的。

Draw graphics

Provide graphics editing capabilities in an application

Create or display bitmap images

Work with PDF documents

對這上面這幾種翻譯一下:

1 )畫圖

這里說的畫圖蒂窒,應(yīng)該是指在界面上畫線條躁倒,多邊形,弧形等洒琢。如股票軟件中的各種線條秧秉。

2)提供圖形編輯功能

圖片編輯功能復(fù)雜一點,如照片處理一類的衰抑。

3)創(chuàng)建或者顯示位圖

4)處理PDF文檔

How to use Quartz2D


concept

我們先理解一些概念象迎,不然理解后面說的東西比較費勁。

1)Painter's model


圖1

看圖1來理解這個所謂的粉刷模型,就是一個粉刷效果砾淌,后面的掩蓋前面的啦撮。

2)The Graphics Context

這個可以理解為繪畫環(huán)境,比如涂鴉繪畫環(huán)境就是墻壁汪厨,油畫的繪畫環(huán)境就是畫布赃春。開發(fā)中的繪畫環(huán)境有:位圖,PDF劫乱,窗口聘鳞,圖層。

Creating a Window Graphics Context要拂,API本身不能獲取window的Context抠璃,需要在Cocoa framework中獲取一個。

CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];//

Creating a PDF Graphics Context

CGPDFContextCreateWithURL

CGPDFContextCreate

Creating a Bitmap Graphics Context

CGBitmapContextCreate

UIGraphicsBeginImageContextWithOptions//iOS環(huán)境中用這個脱惰,避免坐標(biāo)系統(tǒng)的不同

3)Opaque Data Types

數(shù)據(jù)類型很多搏嗡,我們用到的時候在詳細(xì)了解。下面列一下這些數(shù)據(jù)類型和用處:

CGPathRef, used for vector graphics to create paths that you fill or stroke. SeePaths.

CGImageRef, used to represent bitmap images and bitmap image masks based on sample data that you supply. SeeBitmap Images and Image Masks.

CGLayerRef, used to represent a drawing layer that can be used for repeated drawing (such as for backgrounds or patterns) and for offscreen drawing. SeeCore Graphics Layer Drawing

CGPatternRef, used for repeated drawing. SeePatterns.

CGShadingRefandCGGradientRef, used to paint gradients. SeeGradients.

CGFunctionRef, used to define callback functions that take an arbitrary number of floating-point arguments. You use this data type when you create gradients for a shading. SeeGradients.

CGColorRefandCGColorSpaceRef, used to inform Quartz how to interpret color. SeeColor and Color Spaces.

CGImageSourceRefandCGImageDestinationRef, which you use to move data into and out of Quartz. SeeData Management in Quartz 2DandImage I/O Programming Guide.

CGFontRef, used to draw text. SeeText.

CGPDFDictionaryRef,CGPDFObjectRef,CGPDFPageRef,CGPDFStream,CGPDFStringRef,andCGPDFArrayRef, which provide access to PDF metadata. SeePDF Document Creation, Viewing, and Transforming.

CGPDFScannerRefandCGPDFContentStreamRef, which parse PDF metadata. SeePDF Document Parsing.

CGPSConverterRef, used to convert PostScript to PDF. It is not available in iOS. SeePostScript Conversion.

4)Coordinate Systems

在二維中繪圖拉一,坐標(biāo)系的概念必不可少采盒。指標(biāo)系統(tǒng)大家還是比較熟悉的,過多的解釋沒有必要蔚润,值得注意的是在iOS的顯示中坐標(biāo)原點的位置不在左下角而在左上角磅氨。

5)Path

我們想要畫一個三角形或一個圓,在現(xiàn)實中我們可以根據(jù)抽象的思維嫡纠,隨意畫出三角形和圓烦租,但是計算機怎樣能夠準(zhǔn)確的畫出我們想要的圖案呢。Path就是用來定義圖形的除盏〔娉鳎可以理解為Path表示了圖形的輪廓,按照這個輪廓者蠕,通過填充窃祝,描繪就可以準(zhǔn)確的得到我們想要的圖案。

直接在Context上畫

CGContextMoveToPoint

CGContextAddLineToPoint

CGContextAddLines

CGContextAddArc

CGContextAddArcToPoint

CGContextAddCurveToPoint

CGContextAddQuadCurveToPoint

CGContextClosePath

CGContextAddEllipseInRect

CGContextAddRect

創(chuàng)建可復(fù)用的Path

CGPathCreateMutable, which replacesCGContextBeginPath

CGPathMoveToPoint, which replacesCGContextMoveToPoint

CGPathAddLineToPoint, which replacesCGContextAddLineToPoint

CGPathAddCurveToPoint, which replacesCGContextAddCurveToPoint

CGPathAddEllipseInRect, which replacesCGContextAddEllipseInRect

CGPathAddArc, which replacesCGContextAddArc

CGPathAddRect, which replacesCGContextAddRect

CGPathCloseSubpath, which replacesCGContextClosePath

將Path加到Context上CGContextAddPath.

有了Path了我們就可以涂鴉啦踱侣,哦不對粪小,是Paint.有兩種方式,填充(filling)和筆畫(stroking)抡句。

Parameters That Affect Stroking

Parameter:Function to set parameter value

Line width:CGContextSetLineWidth//線寬度

Line join:CGContextSetLineJoin//連接處的風(fēng)格設(shè)置

Line cap:CGContextSetLineCap//兩端的風(fēng)格

Miter limit:CGContextSetMiterLimit //

Line dash pattern:CGContextSetLineDash

Stroke color space:CGContextSetStrokeColorSpace

Stroke color:CGContextSetStrokeColorCGContextSetStrokeColorWithColor

Stroke pattern:CGContextSetStrokePattern

Functions that fill paths

CGContextEOFillPath

Fills the current path using the even-odd rule.

CGContextFillPath

Fills the current path using the nonzero winding number rule.

CGContextFillRect

Fills the area that fits inside the specified rectangle.

CGContextFillRects

Fills the areas that fits inside the specified rectangles.

CGContextFillEllipseInRect

Fills an ellipse that fits inside the specified rectangle.

CGContextDrawPath

Fills the current path if you pass kCGPathFill(nonzero winding number rule) or kCGPathEOFill(even-odd rule). Fills and strokes the current path if you pass kCGPathFillStroke or kCGPathEOFillStroke.

6)Color and Color Space

顏色的相關(guān)內(nèi)容探膊。

7) Transform

如圖,Transform說的就是這樣的一些變換玉转⊥幌耄縮放、移動,旋轉(zhuǎn)等猾担。有坐標(biāo)系作為基礎(chǔ)袭灯,這些變化對應(yīng)相應(yīng)的數(shù)學(xué)知識就很好理解了。簡單的直接調(diào)用API即可绑嘹,復(fù)雜的變換可能要涉及到數(shù)學(xué)內(nèi)容稽荧,比如矩陣變換等,這些東西不在討論范圍工腋。明白可能用到這些就好了


8)Partterns


9)Shadows

陰影可以讓2D的圖形有3D的視覺效果姨丈。

10)Gradient

有時候一種顏色,或者簡單疊加的顏色看起來很枯燥乏味擅腰,我們用漸變讓圖形更豐富蟋恬。

理解了這些東西了,也很無聊的了趁冈,來個例子吧歼争,看看這些東西到底是怎么玩的。

@implementation MyQuartzView

- (id)initWithFrame:(NSRect)frameRect

{

self = [super initWithFrame:frameRect];

return self;

}

- (void)drawRect:(NSRect)rect

{

CGContextRef myContext = [[NSGraphicsContext

currentContext] graphicsPort]; // 1

// ********** Your drawing code here **********// 2

CGContextSetRGBFillColor (myContext, 1, 0, 0, 1);// 3

CGContextFillRect (myContext, CGRectMake (0, 0, 200, 100 ));// 4

CGContextSetRGBFillColor (myContext, 0, 0, 1, .5);// 5

CGContextFillRect (myContext, CGRectMake (0, 0, 100, 200));// 6

}

@end

得到的效果如圖2

1.獲取Context

2.準(zhǔn)備繪圖

3.設(shè)置填充顏色(涉及到Color相關(guān)內(nèi)容)

4.填充矩形區(qū)域(涉及到path相關(guān)內(nèi)容)

5.再次設(shè)置顏色(透明相關(guān))

6.填充矩形區(qū)域(根據(jù)Painter's Model 覆蓋渗勘,重疊區(qū)域的覆蓋)

圖2


Demo

1)QuartzLines

簡單畫線


-(void)drawInContext:(CGContextRef)context

{

// Drawing lines with a white stroke color

CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);

// Draw them with a 2.0 stroke width so they are a bit more visible.

CGContextSetLineWidth(context, 2.0);

// Draw a single line from left to right

CGContextMoveToPoint(context, 10.0, 30.0);

CGContextAddLineToPoint(context, 310.0, 30.0);

CGContextStrokePath(context);

// Draw a connected sequence of line segments

CGPoint addLines[] =

{

CGPointMake(10.0, 90.0),

CGPointMake(70.0, 60.0),

CGPointMake(130.0, 90.0),

CGPointMake(190.0, 60.0),

CGPointMake(250.0, 90.0),

CGPointMake(310.0, 60.0),

};

// Bulk call to add lines to the current path.

// Equivalent to MoveToPoint(points[0]); for(i=1; i < count,++i) AddLineToPoint(points[i]);

CGContextAddLines(context, addLines, sizeof(addLines)/sizeof(addLines[0]));

CGContextStrokePath(context);

CGPoint strokeSegments[] =

{

CGPointMake(10.0, 150.0),

CGPointMake(70.0, 120.0),

CGPointMake(130.0, 150.0),

CGPointMake(190.0, 120.0),

CGPointMake(250.0, 150.0),

CGPointMake(310.0, 120.0),

};

// Bulk call to stroke a sequence of line segments.

CGContextStrokeLineSegments(context, strokeSegments, sizeof(strokeSegments)/sizeof(strokeSegments[0])); ?

cap and join

-(void)drawInContext:(CGContextRef)context

{

// Drawing lines with a white stroke color

CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);

// Preserve the current drawing state

CGContextSaveGState(context);

// Setup the horizontal line to demostrate caps

CGContextMoveToPoint(context, 40.0, 30.0);

CGContextAddLineToPoint(context, 280.0, 30.0);

// Set the line width & cap for the cap demo

CGContextSetLineWidth(context, self.width);

CGContextSetLineCap(context, self.cap);

CGContextStrokePath(context);

// Restore the previous drawing state, and save it again.

CGContextRestoreGState(context);

CGContextSaveGState(context);

// Setup the angled line to demonstrate joins

CGContextMoveToPoint(context, 40.0, 190.0);

CGContextAddLineToPoint(context, 160.0, 70.0);

CGContextAddLineToPoint(context, 280.0, 190.0);

// Set the line width & join for the join demo

CGContextSetLineWidth(context, self.width);

CGContextSetLineJoin(context, self.join);

CGContextStrokePath(context);

// Restore the previous drawing state.

CGContextRestoreGState(context);

// If the stroke width is large enough, display the path that generated these lines

if (self.width >= 4.0) // arbitrarily only show when the line is at least twice as wide as our target stroke

{

CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);

CGContextMoveToPoint(context, 40.0, 30.0);

CGContextAddLineToPoint(context, 280.0, 30.0);

CGContextMoveToPoint(context, 40.0, 190.0);

CGContextAddLineToPoint(context, 160.0, 70.0);

CGContextAddLineToPoint(context, 280.0, 190.0);

CGContextSetLineWidth(context, 2.0);

CGContextStrokePath(context);

}

}

-(void)setCap:(CGLineCap)c

{

if(c != _cap)

{

_cap = c;

[self setNeedsDisplay];

}

}

-(void)setJoin:(CGLineJoin)j

{

if(j != _join)

{

_join = j;

[self setNeedsDisplay];

}

}

-(void)setWidth:(CGFloat)w

{

if(w != _width)

{

_width = w;

[self setNeedsDisplay];

}

}



2)QuartzPoly

3)QuartzGradient

4)QuartzDash

5)QuartzPolygons

6)QuartzCurves

7)QuartzImages

8)QuartzRendering

9) QuartzClipping

2到9的內(nèi)容就不一一貼代碼和貼圖了沐绒。這些內(nèi)容不用記得太清楚,用的時候有個印象能快速查詢到相關(guān)文檔既可以了旺坠。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末乔遮,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子取刃,更是在濱河造成了極大的恐慌蹋肮,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝉衣,死亡現(xiàn)場離奇詭異括尸,居然都是意外死亡巷蚪,警方通過查閱死者的電腦和手機病毡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來屁柏,“玉大人啦膜,你說我怎么就攤上這事√视鳎” “怎么了僧家?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長裸删。 經(jīng)常有香客問我八拱,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任肌稻,我火速辦了婚禮清蚀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘爹谭。我一直安慰自己枷邪,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布诺凡。 她就那樣靜靜地躺著东揣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腹泌。 梳的紋絲不亂的頭發(fā)上嘶卧,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天,我揣著相機與錄音凉袱,去河邊找鬼脸候。 笑死,一個胖子當(dāng)著我的面吹牛绑蔫,可吹牛的內(nèi)容都是我干的运沦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼配深,長吁一口氣:“原來是場噩夢啊……” “哼携添!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起篓叶,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤烈掠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后缸托,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體左敌,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年俐镐,在試婚紗的時候發(fā)現(xiàn)自己被綠了矫限。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡佩抹,死狀恐怖叼风,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情棍苹,我是刑警寧澤无宿,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站枢里,受9級特大地震影響孽鸡,放射性物質(zhì)發(fā)生泄漏蹂午。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一彬碱、第九天 我趴在偏房一處隱蔽的房頂上張望画侣。 院中可真熱鬧,春花似錦堡妒、人聲如沸配乱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搬泥。三九已至,卻和暖如春伏尼,著一層夾襖步出監(jiān)牢的瞬間忿檩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工爆阶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留燥透,地道東北人。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓辨图,卻偏偏與公主長得像班套,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子故河,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,500評論 2 359

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