Quartz 2D繪圖的核心API是CGContextRef,該API專門用於繪製各種圖形。
關注微信公衆號:ioscoding ,分享優質iOS編程技術。by:shuju
1.1 Quartz 2D繪圖基礎:CGContextRef
使用Quartz 2D繪圖的關鍵步驟有兩步:獲取CGContextRef;調用CGContextRef的方法進行繪圖。
不同場景下獲取CGContextRef的方式各不相同,下面介紹iOS開發中最常見的場景下如何獲取CGContextRef。
1. 自定義UIView時獲取CGContextRef
開發自定義UIView的方法是,開發一個繼承UIView的子類,並重寫該UIView的drawRect:方法,當該UIView每次顯示出來時,或該UIView的內容需要更新時,系統都會自動調用該UIView的drawRect:方法。在調用drawRect:方法之前,系統會自動配置繪圖環境,因此,程序只要通過如下函數即可獲取CGContextRef繪圖API:
- CGContextRef ctx = UIGraphicsGetCurrentContext();
獲取CGContextRef之後,即可進行繪圖。
需要指出的是,重寫UIView的drawRect:方法繪圖時,它的繪圖API的座標原點位於該控件的左上角,橫向爲X軸,X座標越大,位置越向右;縱向爲Y軸,Y座標越大,位置越向下。
2. 創建位圖時獲取CGContextRef
如果需要在創建位圖時獲取CGContextRef,那麼程序需要先調用UIGraphicsBeginImageContext()函數來創建內存中的圖片。然後才能調用UIGraphicsGetCurrentContext()獲取繪圖的CGContextRef。例如如下代碼。
- // 創建內存中的圖片
- UIGraphicsBeginImageContext(CGSizeMake(320, 480));
- // 獲取向內存中圖片執行繪圖的CGContextRef
- CGContextRef ctx = UIGraphicsGetCurrentContext();
Quartz 2D繪圖的核心API是CGContextRef,該API並不是一個對象。由於Quartz 2D本身並不是面向對象的,它是面向過程的API,Quartz 2D提供了大量函數來完成繪圖。
Quartz 2D提供的繪圖函數如表1.2所示。
表1.2 Quartz 2D的繪圖相關函數
函數簽名 |
簡要說明 |
void CGContextClearRect(CGContextRef c, CGRect rect); |
擦除指定矩形區域上繪製的圖形 |
void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode); |
使用指定模式繪製當前CGContextRef中所包 含的路徑。第二個參數支持 kCGPathFill、 kCGPathEOFill、kCGPathStroke、kCGPathFillStroke、kCGPathEOFillStroke等枚舉值 |
void CGContextEOFillPath(CGContextRef c); |
使用奇偶規則來填充該路徑包圍的區域。奇 偶規則指:如果某個點被路徑包圍了奇數次, 系統繪製該點;如果被路徑包圍了偶數次,系統不繪製該點 |
void CGContextFillPath(CGContextRef c); |
填充該路徑包圍的區域 |
void CGContextFillRect(CGContextRef c,CGRect rect); |
填充rect代表的矩形 |
void CGContextFillRects(CGContextRef c,const CGRect rects[], size_t count); |
填充多個矩形 |
void CGContextFillEllipseInRect(CGContextRef context, CGRect rect); |
填充rect矩形的內切橢圓區域 |
void CGContextStrokePath(CGContextRef c); |
使用當前 CGContextRef設置的線寬繪製路徑 |
void CGContextStrokeRect(CGContextRef c, CGRect rect); |
使用當前 CGContextRef設置的線寬繪製矩形框 |
void CGContextStrokeRectWithWidth(CGContextRef c, CGRect rect, CGFloat width); |
使用指定線寬繪製矩形框 |
void CGContextReplacePathWithStrokedPath(CGContextRef c); |
使用繪製當前路徑時覆蓋的區域作爲當前CGContextRef 中的新路徑。舉例來說,假如當前CGContextRef包含一 個圓形路徑且線寬爲10,調用該方法後,當前CGContextRef 將包含一個環寬爲10的環形路徑 |
void CGContextStrokeEllipseInRect(CGContextRef context,CGRect rect); |
使用當前 CGContextRef設置的線寬繪製rect矩形的內切橢圓 |
void CGContextStrokeLineSegments(CGContextRef c, const CGPoint points[], size_t count); |
使用當前 CGContextRef設置的線寬繪製多條線段。該 方法需要傳入2N個CGPoint組成的數組,其中1、2個點 組成第一條線段,3、4個點組成第2條線段,以此類推 |
表12.2中的大部分方法都涉及使用路徑,路徑由另一個API:CGPathRef來代表。CGPathRef代表任意多條直線或曲線連接而成的任意圖形,當CGContextRef根據CGPathRef繪製時,它可以繪製出任意的形狀。
關於如何利用CGContextRef來構建路徑和添加路徑,本節後面會有詳細介紹,此處先用最簡單的方法來繪製直線、矩形、橢圓等幾何形狀。
在繪圖之前,還需要對繪圖的顏色、線條粗細等屬性進行設置,Quartz 2D提供瞭如表12.3所示的函數來設置繪圖信息。
表12.3 設置繪圖屬性的相關函數
方法簽名 |
簡要說明 |
void CGContextSaveGState(CGContextRef c); |
保存CGContextRef當前的繪圖狀態,方便以後恢復該狀態 |
void CGContextRestoreGState(CGContextRef c); |
把CGContextRef的狀態恢復到最近一次保存時的狀態 |
CGInterpolationQuality CGContextGetInterpolation Quality(CGContextRef c); |
獲取當前CGContextRef在放大圖片時的插值質量 |
void CGContextSetInterpolationQuality(CGContextRef c, CGInterpolationQuality quality); |
設置當前CGContextRef在放大圖片時的插值質量 |
void CGContextSetLineCap(CGContextRef c, CGLineCap cap); |
設置線段端點的繪製形狀。該屬性支持如下三個值。 kCGLineCapButt:該屬性值指定不繪製端點, 線條結尾處直接結束。這是默認值。 kCGLineCapRound:該屬性值指定繪製圓形端點, 線條結尾處繪製一個直徑爲線條寬度的半圓。 kCGLineCapSquare:該屬性值指定繪製方形端點。 線條結尾處繪製半個邊長爲線條寬度的正方形。需要 說明的是,這種形狀的端點與“butt”形狀的端點十分相似, 只是採用這種形式的端點的線條略長一點而已 |
void CGContextSetLineDash(CGContextRef c, CGFloat phase, const CGFloat lengths[],size_t count); |
設置繪製邊框時所用的點線模式,Quartz 2D支 持非常強大的點線模式。後面會有詳細介紹 |
void CGContextSetLineJoin(CGContextRef c, CGLineJoin join); |
設置線條連接點的風格,該屬性支持如下三個值: kCGLineJoinMeter:這是默認的屬性值。 該方格的連接點形狀如所示。 kCGLineJoinRound:該方格的連接點形狀如 所示。 kCGLineJoinBevel:該方格的連接點形狀如 所示 |
void CGContextSetLineWidth(CGContextRef c, CGFloat width); |
設置繪製直線、邊框時的線條寬度 |
void CGContextSetMiterLimit(CGContextRef c, CGFloat limit); |
當把連接點風格設爲meter風格時,該方法用於控制銳角箭頭的長度 |
void CGContextSetPatternPhase(CGContextRef c, CGSize phase); |
設置該CGContextRef採用位圖填充的相位 |
void CGContextSetFillPattern(CGContextRef c, CGPatternRef pattern,const CGFloat components[]); |
設置該CGContextRef使用位圖填充 |
void CGContextSetShouldAntialias(CGContextRef c, bool shouldAntialias); |
設置該CGContextRef是否應該抗鋸齒(即光滑圖形曲線邊緣) |
void CGContextSetStrokePattern(CGContextRef c, CGPatternRef pattern, const CGFloat components[]); |
設置該CGContextRef使用位圖繪製線條、邊框 |
續表
方法簽名 |
簡要說明 |
||
void CGContextSetBlendMode(CGContextRef context,CGBlendMode mode); |
設置CGContextRef的疊加模式。Quartz 2D 支持多種疊加模式,後面專門有關於疊加模式的介紹 |
||
void CGContextSetAllowsAntialiasing(CGContextRef context, bool allowsAntialiasing); |
設置該CGContextRef是否允許抗鋸齒 |
||
void CGContextSetAllowsFontSmoothing(CGContextRef context, bool allowsFontSmoothing); |
設置該CGContextRef是否允許光滑字體 |
||
void CGContextSetShouldSmoothFonts(CGContextRef c,bool shouldSmoothFonts); |
設置該CGContextRef是否允許光滑字體 |
||
void CGContextSetAlpha (CGContextRef c, CGFloat alpha); |
設置全局透明度 |
||
void CGContextSetCMYKFillColor(CGContextRef c, CGFloat cyan, CGFloat magenta, CGFloat yellow,CGFloat black, CGFloat alpha); |
使用CMYK顏色模式來設置該CGContextRef的填充顏色 |
||
void CGContextSetCMYKStrokeColor(CGContextRef c, CGFloat cyan, CGFloat magenta, CGFloat yellow,CGFloat black, CGFloat alpha); |
使用CMYK顏色模式來設置該CGContextRef的線條顏色 |
||
void CGContextSetFillColorWithColor(CGContextRef c, CGColorRef color); |
使用指定顏色來設置該CGContextRef的填充顏色 |
||
void CGContextSetStrokeColorWithColor(CGContextRef c, CGColorRef color); |
使用指定顏色來設置該CGContextRef的線條顏色 |
||
void CGContextSetGrayFillColor(CGContextRef c, CGFloat gray, CGFloat alpha); |
使用灰色來設置該CGContextRef的填充顏色 |
||
void CGContextSetGrayStrokeColor(CGContextRef c, CGFloat gray, CGFloat alpha); |
使用灰色來設置該CGContextRef的線條顏色 |
||
void CGContextSetRGBFillColor(CGContextRef c, CGFloat gray, CGFloat alpha); |
使用RGB顏色模式來設置該CGContextRef的填充顏色 |
||
void CGContextSetRGBStokeColor(CGContextRef c, CGFloat gray, CGFloat alpha); |
使用RGB顏色模式來設置該CGContextRef的線條顏色 |
||
void CGContextSetShadow(CGContextRef context, CGSize offset, CGFloat blur); |
設置陰影在X、Y方向上的偏移,以及模糊度(blur 值越大,陰影越模糊)。該函數沒有設置陰影顏色, 默認使用1/3透明的黑色(即RGBA{0, 0, 0, 1.0/3.0})作爲陰影顏色 |
||
void CGContextSetShadowWithColor(CGContextRef context, CGSize offset, CGFloat blur, CGColorRef color); |
設置陰影在X、Y方向上的偏移,以及模糊度和陰影的顏色 |