繪圖方面總結(jié)

學(xué)習(xí)繪圖教程的總結(jié)

使用框架:Core Graphics FrameWork

iOS支持兩套圖形API族:Core Graphics/QuartZ 2D 和OpenGL ES。

OpenGL ES是跨平臺的圖形API,屬于OpenGL的一個簡化版本。QuartZ 2D是蘋果公司開發(fā)的一套API,它是Core Graphics Framework的一部分。

注意點:

1、Core Graphics API 操作都在上下文中進行。圖形上下文理解為一快畫布。

2、所有繪圖操作結(jié)束后需要關(guān)閉圖形上下文。

3、使用UIKit只能在當(dāng)前上下文中進行。

4、UIGraphicsPushContext

將context轉(zhuǎn)化為當(dāng)前上下文

UIGraphicsPopContext

5、UIGraphicsBeginImageContextWithOptions 創(chuàng)建的上下文就是當(dāng)前上下文

6、

UIGraphicsBeginImageContextWithOptions(CGSizeMake(100,100),?NO,?0);

UIGraphicsBeginImageContextWithOptions函數(shù)參數(shù)的含義:第一個參數(shù)表示所要創(chuàng)建的圖片的尺寸;第二個參數(shù)用來指定所生成圖片的背景是否為不透明,如上我們使用YES而不是NO,則我們得到的圖片背景將會是黑色,顯然這不是我想要的;第三個參數(shù)指定生成圖片的縮放因子,這個縮放因子與UIImage的scale屬性所指的含義是一致的。傳入0則表示讓圖片的縮放因子根據(jù)屏幕的分辨率而變化,所以我們得到的圖片不管是在單分辨率還是視網(wǎng)膜屏上看起來都會很好。

許多的屬性組成了一個圖形上下文狀態(tài),這些屬性設(shè)置決定了在你繪圖時圖形的外觀和行為。下面我列出了一些屬性和對應(yīng)修改屬性的函數(shù);雖然這些函數(shù)是關(guān)于Core Graphics的,但記住,實際上UIKit同樣是調(diào)用這些函數(shù)操縱上下文狀態(tài)。

線條的寬度和線條的虛線樣式

CGContextSetLineWidth、CGContextSetLineDash

線帽和線條聯(lián)接點樣式

CGContextSetLineCap、CGContextSetLineJoin、CGContextSetMiterLimit

線條顏色和線條模式

CGContextSetRGBStrokeColor、CGContextSetGrayStrokeColor、CGContextSetStrokeColorWithColor、CGContextSetStrokePattern

填充顏色和模式

CGContextSetRGBFillColor,CGContextSetGrayFillColor,CGContextSetFillColorWithColor, CGContextSetFillPattern

陰影

CGContextSetShadow、CGContextSetShadowWithColor

混合模式

CGContextSetBlendMode(決定你當(dāng)前繪制的圖形與已經(jīng)存在的圖形如何被合成)

整體透明度

CGContextSetAlpha(個別顏色也具有alpha成分)

文本屬性

CGContextSelectFont、CGContextSetFont、CGContextSetFontSize、CGContextSetTextDrawingMode、CGContextSetCharacterSpacing

是否開啟反鋸齒和字體平滑

CGContextSetShouldAntialias、CGContextSetShouldSmoothFonts

另外一些屬性設(shè)置:

裁剪區(qū)域:在裁剪區(qū)域外繪圖不會被實際的畫出來。

變換(或稱為“CTM“,意為當(dāng)前變換矩陣): 改變你隨后指定的繪圖命令中的點如何被映射到畫布的物理空間。

許多這些屬性設(shè)置接下來我都會舉例說明。

路徑與繪圖

通過編寫移動虛擬畫筆的代碼描畫一段路徑,這樣的路徑并不構(gòu)成一個圖形。繪制路徑意味著對路徑描邊或填充該路徑,也或者兩者都做。同樣,你應(yīng)該從某些繪圖程序中得到過相似的體會。

一段路徑是由點到點的描畫構(gòu)成。想象一下繪圖系統(tǒng)是你手里的一只畫筆,你首先必須要設(shè)置畫筆當(dāng)前所處的位置,然后給出一系列命令告訴畫筆如何描畫隨后的每段路徑。每一段新增的路徑開始于當(dāng)前點,當(dāng)完成一條路徑的描畫,路徑的終點就變成了當(dāng)前點。

下面列出了一些路徑描畫的命令:

定位當(dāng)前點

CGContextMoveToPoint

描畫一條線

CGContextAddLineToPoint、CGContextAddLines

描畫一個矩形

CGContextAddRect、CGContextAddRects

描畫一個橢圓或圓形

CGContextAddEllipseInRect

描畫一段圓弧

CGContextAddArcToPoint、CGContextAddArc

通過一到兩個控制點描畫一段貝賽爾曲線

CGContextAddQuadCurveToPoint、CGContextAddCurveToPoint

關(guān)閉當(dāng)前路徑

CGContextClosePath 這將從路徑的終點到起點追加一條線。如果你打算填充一段路徑,那么就不需要使用該命令,因為該命令會被自動調(diào)用。

描邊或填充當(dāng)前路徑

CGContextStrokePath、CGContextFillPath、CGContextEOFillPath、CGContextDrawPath。對當(dāng)前路徑描邊或填充會清除掉路徑。如果你只想使用一條命令完成描邊和填充任務(wù),可以使用CGContextDrawPath命令,因為如果你只是使用CGContextStrokePath對路徑描邊,路徑就會被清除掉,你就不能再對它進行填充了。

創(chuàng)建路徑并描邊路徑或填充路徑只需一條命令就可完成的函數(shù):CGContextStrokeLineSegments、CGContextStrokeRect、CGContextStrokeRectWithWidth、CGContextFillRect、CGContextFillRects、CGContextStrokeEllipseInRect、CGContextFillEllipseInRect。

一段路徑是被合成的,意思是它是由多條獨立的路徑組成。舉個例子,一條單獨的路徑可能由兩個獨立的閉合形狀組成:一個矩形和一個圓形。當(dāng)你在構(gòu)造一條路徑的中間過程(意思是在描畫了一條路徑后沒有調(diào)用描邊或填充命令,或調(diào)用CGContextBeginPath函數(shù)來清除路徑)調(diào)用CGContextMoveToPoint函數(shù),就像是你拾起畫筆,并將畫筆移動到一個新的位置,如此來準(zhǔn)備開始一段獨立的相同路徑。如果你擔(dān)心當(dāng)你開始描畫一條路徑的時候,已經(jīng)存在的路徑和新的路徑會被認為是已存在路徑的一個合成部分,你可以調(diào)用CGContextBeginPath函數(shù)指定你繪制的路徑是一條獨立的路徑;蘋果的許多例子都是這樣做的,但在實際開發(fā)中我發(fā)現(xiàn)這是非必要的。

CGContextClearRect函數(shù)的功能是擦除一個區(qū)域。這個函數(shù)會擦除一個矩形內(nèi)的所有已存在的繪圖;并對該區(qū)域執(zhí)行裁剪。結(jié)果像是打了一個貫穿所有已存在繪圖的孔。

CGContextClearRect函數(shù)的行為依賴于上下文是透明還是不透明。當(dāng)在圖形上下文中繪圖時,這會尤為明顯和直觀。如果圖片上下文是透明的(UIGraphicsBeginImageContextWithOptions第二個參數(shù)為NO),那么CGContextClearRect函數(shù)執(zhí)行擦除后的顏色為透明,反之則為黑色。

當(dāng)在一個視圖中直接繪圖(使用drawRect:或drawLayer:inContext:方法),如果視圖的背景顏色為nil或顏色哪怕有一點點透明度,那么CGContextClearRect的矩形區(qū)域?qū)@示為透明的,打出的孔將穿過視圖包括它的背景顏色。如果背景顏色完全不透明,那么CGContextClearRect函數(shù)的結(jié)果將會是黑色。這是因為視圖的背景顏色決定了是否視圖的圖形上下文是透明的還是不透明的。

如圖5,在左邊的藍色正方形被挖去部分留為黑色,然而在右邊的藍色正方形也被挖去部分留為透明。但這兩個正方形都是UIView子類的實例,采用相同的繪圖代碼!不同之處在于視圖的背景顏色,左邊的正方形的背景顏色在nib文件中

獲取上下文方法:

1、第一種方法就是創(chuàng)建一個圖片類型的上下文。調(diào)用UIGraphicsBeginImageContextWithOptions函數(shù)就可獲得用來處理圖片的圖形上下文。利用該上下文,你就可以在其上進行繪圖,并生成圖片。調(diào)用UIGraphicsGetImageFromCurrentImageContext函數(shù)可從當(dāng)前上下文中獲取一個UIImage對象。記住在你所有的繪圖操作后別忘了調(diào)用UIGraphicsEndImageContext函數(shù)關(guān)閉圖形上下文。

2、第二種方法是利用cocoa為你生成的圖形上下文。當(dāng)你子類化了一個UIView并實現(xiàn)了自己的drawRect:方法后,一旦drawRect:方法被調(diào)用,Cocoa就會為你創(chuàng)建一個圖形上下文,此時你對圖形上下文的所有繪圖操作都會顯示在UIView上。

判斷一個上下文是否為當(dāng)前圖形上下文需要注意的幾點:

1.UIGraphicsBeginImageContextWithOptions函數(shù)不僅僅是創(chuàng)建了一個適用于圖形操作的上下文,并且該上下文也屬于當(dāng)前上下文。

2.當(dāng)drawRect方法被調(diào)用時,UIView的繪圖上下文屬于當(dāng)前圖形上下文。

3.回調(diào)方法所持有的context:參數(shù)并不會讓任何上下文成為當(dāng)前圖形上下文。此參數(shù)僅僅是對一個圖形上下文的引用罷了。

UIKit

像UIImage、NSString(繪制文本)、UIBezierPath(繪制形狀)、UIColor都知道如何繪制自己。這些類提供了功能有限但使用方便的方法來讓我們完成繪圖任務(wù)。一般情況下,UIKit就是我們所需要的。

使用UiKit,你只能在當(dāng)前上下文中繪圖,所以如果你當(dāng)前處于UIGraphicsBeginImageContextWithOptions函數(shù)或drawRect:方法中,你就可以直接使用UIKit提供的方法進行繪圖。如果你持有一個context:參數(shù),那么使用UIKit提供的方法之前,必須將該上下文參數(shù)轉(zhuǎn)化為當(dāng)前上下文。幸運的是,調(diào)用UIGraphicsPushContext 函數(shù)可以方便的將context:參數(shù)轉(zhuǎn)化為當(dāng)前上下文,記住最后別忘了調(diào)用UIGraphicsPopContext函數(shù)恢復(fù)上下文環(huán)境。

Core Graphics

使用注意:

1、需要指定圖形上下文(CGContextRef)

這是一個繪圖專用的API族,它經(jīng)常被稱為QuartZ或QuartZ 2D。Core Graphics是iOS上所有繪圖功能的基石,包括UIKit。

使用Core Graphics之前需要指定一個用于繪圖的圖形上下文(CGContextRef),這個圖形上下文會在每個繪圖函數(shù)中都會被用到。如果你持有一個圖形上下文context:參數(shù),那么你等同于有了一個圖形上下文,這個上下文也許就是你需要用來繪圖的那個。如果你當(dāng)前處于UIGraphicsBeginImageContextWithOptions函數(shù)或drawRect:方法中,并沒有引用一個上下文。為了使用Core Graphics,你可以調(diào)用UIGraphicsGetCurrentContext函數(shù)獲得當(dāng)前的圖形上下文。

6種繪圖形式:

第一種繪圖形式:在UIView的子類方法drawRect:中繪制一個藍色圓,使用UIKit在Cocoa為我們提供的當(dāng)前上下文中完成繪圖任務(wù)。

-?(void)?drawRect:?(CGRect)?rect?{

UIBezierPath*?p?=?[UIBezierPathbezierPathWithOvalInRect:CGRectMake(0,0,100,100)];

[[UIColor?blueColor]?setFill];

[p?fill];

}

第二種繪圖形式:使用Core Graphics實現(xiàn)繪制藍色圓

-?(void)?drawRect:?(CGRect)?rect?{

CGContextRef?con?=?UIGraphicsGetCurrentContext();

CGContextAddEllipseInRect(con,?CGRectMake(0,0,100,100));

CGContextSetFillColorWithColor(con,?[UIColor?blueColor].CGColor);

CGContextFillPath(con);

}

第三種繪圖形式:我將在UIView子類的drawLayer:inContext:方法中實現(xiàn)繪圖任務(wù)

-?(void)drawLayer:(CALayer*)layer?inContext:(CGContextRef)ctx?{

UIGraphicsPushContext(ctx);

UIBezierPath*?p?=?[UIBezierPath?bezierPathWithOvalInRect:CGRectMake(0,0,100,100)];

[[UIColor?blueColor]?setFill];

[p?fill];

UIGraphicsPopContext();

}

第四種繪圖形式:使用Core Graphics在drawLayer:inContext:方法實現(xiàn)同樣操作

-?(void)drawLayer:(CALayer*)lay?inContext:(CGContextRef)con?{

CGContextAddEllipseInRect(con,?CGRectMake(0,0,100,100));

CGContextSetFillColorWithColor(con,?[UIColor?blueColor].CGColor);

CGContextFillPath(con);

}

演示UIGraphicsBeginImageContextWithOptions的用法,并從上下文中生成一個UIImage對象。生成UIImage對象的代碼并不需要等待某些方法被調(diào)用后或在UIView的子類中才能去做。

第五種繪圖形式:使用UIKit實現(xiàn):

UIGraphicsBeginImageContextWithOptions(CGSizeMake(100,100),?NO,?0);

UIBezierPath*?p?=?[UIBezierPath?bezierPathWithOvalInRect:CGRectMake(0,0,100,100)];

[[UIColor?blueColor]?setFill];

[p?fill];

UIImage*?im?=?UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

第六種繪圖形式:使用Core Graphics實現(xiàn):

UIGraphicsBeginImageContextWithOptions(CGSizeMake(100,100),?NO,?0);

CGContextRef?con?=?UIGraphicsGetCurrentContext();

CGContextAddEllipseInRect(con,?CGRectMake(0,0,100,100));

CGContextSetFillColorWithColor(con,?[UIColor?blueColor].CGColor);

CGContextFillPath(con);

UIImage*?im?=?UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

example:

(1.獲取上下文,注意我們并沒有拿到上下文的 CGContextRef 引用 :

UIGraphicsBeginImageContextWithOptions(CGRectMake(0,0,100,100),?NO,0.0);

(2. 在上下文中進行繪制.

(3.最后生成繪制的圖片

UIImage*image?=UIGraphicsGetImageFromCurrentImageContext();

(4.關(guān)閉上下文

UIGraphicsEndImageContext();

參考資料:

1、http://www.cocoachina.com/industry/20140115/7703.html

2、http://www.lxweimin.com/p/fe0aab588b40

3、http://www.cnblogs.com/wendingding/p/3782679.html

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

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