iOS 繪圖API之Core Graphics系統(tǒng)學(xué)習(xí)(一)

前言

??iOS支持兩套圖形API族:Core Graphics和OpenGL ES。OpenGL ES是跨平臺的圖形API,屬于OpenGL的一個簡化版本。而QuartZ 2D是蘋果公司開發(fā)的一套API,它是Core Graphics Framewore的一部分。
??本文中主要是對Core Graphics框架的學(xué)習(xí)總結(jié)。

??對于一個初學(xué)者來說,UIKit和Core Graphics兩個支持繪圖的框架常常令我們感到迷惑。

UIKit

??UIKit是一組Objective-C API,為線條圖形、Quartz圖像和顏色操作提供Objective-C封裝,并提供2D繪制、圖像處理及用戶接口級別的動畫。
??UIKit包含UIBezierPath(繪制線、角度、橢圓及其它圖形)、UIImage(顯示圖像)、UIColor(顏色操作)、UIFont和UIScreen(提供字體和屏幕信息)等類,它在位圖圖形環(huán)境、PDF圖形環(huán)境上進(jìn)行繪制和操作功能,也提供對標(biāo)準(zhǔn)視圖的支持,也提供對打印功能的支持。
??使用UIKit,你只能在當(dāng)前上下文中繪圖。

Core Graphics

??這是一個繪圖專用的API族,它經(jīng)常被稱為QuartZ或者QuartZ 2D。Core Graphics 是iOS上所有繪圖功能的基石,包括UIKit(UIKit是對Core Graphics的進(jìn)一步封裝)。
??使用Core Graphics之前需要指定一個用于繪圖的圖形上下文(CGContextRef),這個圖形上下文會在每個繪圖函數(shù)中都會用到。

??至此,我們了解了這兩個框架的基本關(guān)系,而這兩個框架中都提到了圖形上下文(圖形場景)。獲得一個圖形上下文是我們完成繪圖任務(wù)的第一步,可以將圖形上下文理解為一塊畫布。那么下邊介紹三種獲得圖形上下文的方法:

- (void)drawRect:(CGRect)rect方法

??在此方法中,UIKit框架可以直接繪圖,而Core Graphics可以通過UIGraphicsGetCurrentContext函數(shù)獲取當(dāng)前的圖形上下文。

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

??在此方法中,直接傳入了圖形上下文,但是該上下文不一定是當(dāng)前的圖形上下文,所以在UIKit框架下繪圖時(shí),需要調(diào)用UIGraphicsPushContext()函數(shù)將該上下文變?yōu)楫?dāng)前上下文,結(jié)束時(shí)調(diào)用UIGraphicsPopContext()函數(shù)還原上下文。而Core Graphics框架下可以直接使用該上下文。

UIGraphicsBeginImageContextWithOptions函數(shù)

??此函數(shù)獲取圖形上下文的規(guī)則跟drawRect:方法是一樣的。利用該上下文,你就可以在其上進(jìn)行繪圖,并生成圖片。調(diào)用UIGraphicsGetImageFromCurrentImageContext函數(shù)可從當(dāng)前上下文中獲取一個UIImage對象。記住在你所有的繪圖操作后別忘了調(diào)用UIGraphicsEndImageContext函數(shù)關(guān)閉圖形上下文。
??這里主要解釋一下三個參數(shù)的含義。第一個參數(shù)表示所要創(chuàng)建的圖片尺寸;第二個參數(shù)用來指定生成圖片的背景是否為不透明,YES表示不透明,則得到的是黑色的背景;第三個參數(shù)制定生成圖片的縮放因子,這個縮放因子與UIImage的scale屬性所指的含義是一致的。0則表示讓圖片的縮放因子根據(jù)屏幕的分辨率而變化。

基于兩大繪圖框架和三種獲取圖形上下文的方法的六種繪圖形式

舉例說明:繪制一個藍(lán)色的圓
第一種繪圖形式:基于UIKit框架(即使用UIBezierPath)在UIView的子類方法drawRect:中實(shí)現(xiàn)。

- (void) drawRect: (CGRect) rect {
   UIBezierPath* p = [UIBezierPathbezierPathWithOvalInRect:CGRectMake(0,0,100,100)];
   [[UIColor blueColor] setFill];
   [p fill];
}

第二種繪圖形式:基于Core Graphics框架在UIView的子類方法drawRect:中實(shí)現(xiàn)。

- (void) drawRect: (CGRect) rect {
    CGContextRef con = UIGraphicsGetCurrentContext();
    CGContextAddEllipseInRect(con, CGRectMake(0,0,100,100));
    CGContextSetFillColorWithColor(con, [UIColor blueColor].CGColor);
    CGContextFillPath(con);
}

第三種繪圖形式:基于UIKit框架(即使用UIBezierPath) 在UIView的子類方法drawLayer:inContext:中實(shí)現(xiàn)。

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
    [super drawLayer:layer inContext:ctx];
    UIGraphicsPushContext(ctx);
    UIBezierPath* p = [UIBezierPathbezierPathWithOvalInRect:CGRectMake(0,0,100,100)];
    [[UIColor blueColor] setFill];
    [p fill];
    UIGraphicsPopContext();
}

PS:同時(shí)此方法必須重寫drawRect:方法,否則上邊的方法不會被調(diào)用。
詳細(xì)了解這塊的調(diào)用邏輯可以看這篇文章
iOS的繪圖之drawRect和drawLayer:inContext
第四種繪圖形式: 使用Core Graphics在drawLayer:inContext:方法中實(shí)現(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對象的代碼可以在任何地方被使用,它沒有上述繪圖方法那樣的限制。

第五種繪圖形式: 使用UIKit實(shí)現(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實(shí)現(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();

UIKit和Core Graphics可以在相同的圖形上下文中混合使用。在iOS 4.0之前,使用UIKit和UIGraphicsGetCurrentContext被認(rèn)為是線程不安全的。而在iOS4.0以后蘋果讓繪圖操作在第二個線程中執(zhí)行解決了此問題。

寫在最后的話

從開始研究這個框架看了很多文章,收獲很多,慢慢從這些文章中一點(diǎn)點(diǎn)的找到它們之間的關(guān)系,這個過程是曲折的,但也是喜悅的。后續(xù)還會更新,本篇文章只是開始,一點(diǎn)點(diǎn)皮毛。

借鑒的文章

iOS 圖形編程總結(jié)
iOS繪圖教程
iOS繪圖框架CoreGraphics分析

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Core Graphics Framework是一套基于C的API框架,使用了Quartz作為繪圖引擎。它提供了低...
    ShanJiJi閱讀 1,736評論 0 20
  • 原文地址:http://www.cocoachina.com/industry/20140115/7703.htm...
    默默_David閱讀 6,260評論 0 1
  • 緩了幾日沒動靜,報(bào)章沒新聞,沒人再找他們麻煩,就連公司的業(yè)務(wù)也出奇的順利。便找?guī)煾颠x了黃道吉日,妥妥當(dāng)當(dāng)安排了千佑...
    籽鹽閱讀 493評論 0 0
  • 每個人人生當(dāng)中都會經(jīng)歷無數(shù)次選擇,不同的選擇造就了不同的人生,如何做出最優(yōu)選擇,如何避開不利選擇,這就變成...
    陌上可妍閱讀 816評論 0 2

友情鏈接更多精彩內(nèi)容