標籤:
一、Quartz2D簡介
1、什麼是Quartz2D
Quartz 2D是一個二維繪圖引擎,同時支援iOS和Mac系統
Quartz 2D能完成的工作
繪製圖形 : 線條\三角形\矩形\圓\弧等
繪製文字
繪製\產生圖片(映像)
讀取\產生PDF
\裁剪圖片
自訂UI控制項
2、Quartz2D執行個體
Quartz 2D能做很多強大的事情,例如
裁剪圖片
塗鴉\畫板
手勢解鎖
報表:折線圖\餅狀圖\柱狀圖
二、自訂view
1、Quartz2D在iOS開發中的價值
為了便於搭建美觀的UI介面,iOS提供了UIKit架構,裡面有各種各樣的UI控制項
UILabel:顯示文字
UIImageView:顯示圖片
UIButton:同時顯示圖片和文字(能點擊)
… …
利用UIKit架構提供的控制項,拼拼湊湊,能搭建和現實一些簡單、常見的UI介面
但是,有些UI介面極其複雜、而且比較個人化,用普通的UI控制項無法實現,這時可以利用Quartz2D技術將控制項內部的結構畫出來,自訂控制項的樣子
其實,iOS中大部分控制項的內容都是通過Quartz2D畫出來的
因此,Quartz2D在iOS開發中很重要的一個價值是:自訂view(自訂UI控制項)
2、圖形上下文
圖形上下文(Graphics Context):是一個CGContextRef類型的資料
圖形內容相關的作用
儲存繪圖資訊、繪圖狀態
決定繪製的輸出目標(繪製到什麼地方去?)
(輸出目標可以是PDF檔案、Bitmap或者顯示器的視窗上)
相同的一套繪圖序列,指定不同的Graphics Context,就可將相同的映像繪製到不同的目標上
Quartz2D提供了以下幾種類型的Graphics Context:
Bitmap Graphics Context
PDF Graphics Context
Window Graphics Context
Layer Graphics Context
Printer Graphics Context
3、自訂view
如何利用Quartz2D繪製東西到view上?
首先,得有圖形上下文,因為它能儲存繪圖資訊,並且決定著繪製到什麼地方去
其次,那個圖形上下文必須跟view相關聯,才能將內容繪製到view上面
自訂view的步驟
建立一個類,繼承自UIView
實現- (void)drawRect:(CGRect)rect方法,然後在這個方法中
取得跟當前view相關聯的圖形上下文
繪製相應的圖形內容
利用圖形上下文將繪製的所有內容渲染顯示到view上面
4、drawRect:
為什麼要實現drawRect:方法才能繪圖到view上?
因為在drawRect:方法中才能取得跟view相關聯的圖形上下文
drawRect:方法在什麼時候被調用?
當view第一次顯示到螢幕上時(被加到UIWindow上顯示出來)
調用view的setNeedsDisplay或者setNeedsDisplayInRect:時
5、繪圖順序
6、Quartz2D須知
Quartz2D的API是純C語言的
Quartz2D的API來自於Core Graphics架構
資料類型和函數基本都以CG作為首碼
CGContextRef
CGPathRef
CGContextStrokePath(ctx);
……
7、drawRect:中取得的上下文(View為什麼能顯示東西)
在drawRect:方法中取得上下文後,就可以繪製東西到view上
View內部有個layer(圖層)屬性,drawRect:方法中取得的是一個Layer Graphics Context,因此,繪製的東西其實是繪製到view的layer上去了
View之所以能顯示東西,完全是因為它內部的layer
三、繪圖實現
1、Quartz2D繪圖的代碼步驟
1)獲得圖形上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
2)拼接路徑(下面代碼是搞一條線段)
CGContextMoveToPoint(ctx, 10, 10);CGContextAddLineToPoint(ctx, 100, 100);
3)繪製路徑
CGContextStrokePath(ctx); // CGContextFillPath(ctx);
2、常用拼接路徑函數
建立一個起點
void CGContextMoveToPoint(CGContextRef c, CGFloat x, CGFloat y)
添加新的線段到某個點
void CGContextAddLineToPoint(CGContextRef c, CGFloat x, CGFloat y)
添加一個矩形
void CGContextAddRect(CGContextRef c, CGRect rect)
添加一個橢圓
void CGContextAddEllipseInRect(CGContextRef context, CGRect rect)
添加一個圓弧
void CGContextAddArc(CGContextRef c, CGFloat x, CGFloat y, CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)
3、常用繪製路徑函數
Mode參數決定繪製的模式
void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode)
繪製空心路徑
void CGContextStrokePath(CGContextRef c)
繪製實心路徑
void CGContextFillPath(CGContextRef c)
提示:一般以CGContextDraw、CGContextStroke、CGContextFill開頭的函數,都是用來繪製路徑的
4、圖形上下文棧的操作
將當前的上下文copy一份,儲存到棧頂(那個棧叫做”圖形上下文棧”)
void CGContextSaveGState(CGContextRef c)
將棧頂的上下文出棧,替換掉當前的上下文
void CGContextRestoreGState(CGContextRef c)
5、矩陣操作
利用矩陣操作,能讓繪製到上下文中的所有路徑一起發生變化
縮放
void CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)
旋轉
void CGContextRotateCTM(CGContextRef c, CGFloat angle)
平移
void CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)
6、Quartz2D的記憶體管理
使用含有“Create”或“Copy”的函數建立的對象,使用完後必須釋放,否則將導致記憶體泄露
使用不含有“Create”或“Copy”的函數擷取的對象,則不需要釋放
如果retain了一個對象,不再使用時,需要將其release掉
可以使用Quartz 2D的函數來指定retain和release一個對象。例如,如果建立了一個CGColorSpace對象,則使用函數CGColorSpaceRetain和CGColorSpaceRelease來retain和release對象。
也可以使用Core Foundation的CFRetain和CFRelease。注意不能傳遞NULL值給這些函數
四、實用功能
1、圖片浮水印
浮水印:在圖片上加的防止他人盜圖的半透明logo、文字、表徵圖
浮水印的作用
告訴你這個圖片從哪來的
主要是一些網站為了著作權問題、廣告而添加的
有時候,在手機用戶端app中也需要用到浮水印技術
比如,使用者拍完照片後,可以在照片上打個浮水印,標識這個圖片是屬於哪個使用者的
實現方式:利用Quartz2D,將浮水印(文字、LOGO)畫到圖片的右下角
核心代碼
開啟一個基於位元影像的圖形上下文
void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)
從上下文中取得圖片(UIImage)
UIImage* UIGraphicsGetImageFromCurrentImageContext();
結束基於位元影像的圖形上下文
void UIGraphicsEndImageContext();
2、圖片裁剪
很多app的頭像,都是圓形的
這時需要把一張普通的圖片刻意裁剪成圓形
核心代碼
void CGContextClip(CGContextRef c)
將當前上下所繪製的路徑裁剪出來(超出這個裁剪地區的都不能顯示)
3、螢幕
有時候需要截取螢幕上的某一塊內容
核心代碼
- (void)renderInContext:(CGContextRef)ctx;
調用某個view的layer的renderInContext:方法即可
IOS開發——UI進階篇(十五)Quartz2D介紹