iOS--Quartz2D(上)

一、Quartz2D基本概念

1、Quartz2D是一個二維圖形繪制引擎,支持iOS環境和Mac OS X環境

2、Quartz2D API可以實現很多功能,如基于路徑的繪圖、透明度、陰影、顏色管理、反鋸齒、PDF文檔生成和PDF元數據訪問等

3、Quartz2D API是Core Graphics框架的一部分,因此其中的很多數據類型和方法都是以CG開頭的

4、Quartz2D與分辨率和設備無關,因此在使用Quartz2D繪圖時,無需考慮最終繪圖的目標設備

二、Core Graphics? ??

1、該框架是一組基于C的API,可以用于一切繪圖操作,這個框架的重要性,僅次于UIKit和Foundation? ??

2、當使用UIKit創建按鈕、標簽或者其他UIView的子類時,UIKit會用Core Graphics將這些元素繪制在屏幕上,此外,UIEvent也會使用Core Graphics,用來幫組確定觸摸時間在屏幕上所處的位置? ??

3、因為UIKit依賴于Core Graphics,所以當引入時,Core Graphics框架會被自動引入

4、為了讓開發者不必觸及底層的Core Graphics的C接口,UIKit內部封裝了Core Graphics的一些API,可以快速生成通用的界面元素,但是,有時候直接利用Core Graphics的C接口是很有必要和很有好處的,比如創建一個自定義的界面元素

三、Quartz2D的幾個重要概念

1、圖像上下文(Graphics Context) - 相當于一個畫筆

1) Graphics Context是一個數據類型(CGContextRef),封裝了Quartz繪制圖像到輸出設備的信息,輸出設備可以是PDF文件、Bitmap(位圖文件,一種圖形文件)或者顯示器的窗口上

2)Quartz中所有的對象都是繪制到一個Graphics Context中

3)當用Quartz繪圖時,所有設備相關的特性都包含在Graphics Context中,換句話說,我們可以簡單地給Quartz繪圖序列指定不同的Graphics Context,就可將相同的圖像繪制在不同的設備上,而不需要任何設備相關的計算,這些都有Quartz替我們完成

2、Quartz2D坐標系

1)Quartz中默認的坐標系統是:原定(0,0)在左下角,沿著X軸從左到右坐標值逐漸增大,沿著Y軸從下到上左鍵增加

2)有些技術在設置他們的graphics Context時使用了不同于Quartz的默認坐標系統,最常見的是系統原點修改為左上角

3)坐標系的轉換

//相對原點旋轉上下文坐標系

CGContextRotateCTM(CGContextRef c, CGFloat angle)

//相對原點平移上下文坐標系

CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)

//縮放上下文坐標系

CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)

PS:

注意:

轉換坐標系前,使用方法保存當前上下文狀態

CGContextSaveGState(CGContextRef c)

坐標系轉換后,使用方法恢復之前保存的上下文狀態

CGContextRestoreGState(CGContextRef c)可以

3、Quartz2D的繪圖順序

1)誰后繪制誰顯示在頂部,即疊加到最上面

2)利用Quartz2D繪制UIView

當在UIView子類中重寫drawRect方法時,iOS會自動準備好一個圖像上下文,可以通過調用UIGraphicsGetCurrentContext()來獲取

3)只要一個UIView需要被刷新或者重繪,drawRect方法就會被調用,需要注意的是:重繪時應該調用setneedsDisplay,而不能直接調用drawRect,setNeedsDisplay會自動調用drawRect:

4) drawRect注意事項

drawRect:是在UIViewController的loadView和viewDidLoad兩方法之后調用的

drawRect:如果試圖沒有設置frame,將導致該方法不能執行

如果設置UIView的contentMode屬性值為UIViewContentModeRedraw,那么將在每次更改frame時自動調用drawRect:

如果使用UIView繪圖,只能在drawRect:方法中獲取相應的CGContextRef并繪圖,而在其他方法中獲取的CGContextRef不能用于繪圖

4、Quartz內存管理

1)使用含有"Create"或"Copy"的函數創建的對象,使用完后必須釋放,否則將導致內存泄露,使用不含有"Create"或"Copy"的函數獲取的對象,則不需要釋放

2)如果retain了一個對象,不再使用時需要將其release掉,可以使用Quratz2D的函數來指定retain和release一個對象,例如創建了一個CGColorSpace對象,則使用函數CGColorSpaceRetain和CGColorSpaceRelease來retain和release對象,也可以使用CoreFoundation的CFRetain和CGRelease。注意不能傳遞NULL值給這些函數

5、Quartz2D繪圖的基礎元素-路徑

路徑定義了一條或者多條形狀或子路徑

子路徑可以包含一條或者多條直線或曲線

子路徑也可以是一些簡單的形狀,例如線、圓形、矩形或者星型等

子路徑還可以包含復雜的形狀,例如地圖輪廓或者涂鴉等

路徑是可以是開放的,也可以是封閉的,對于封閉路徑可以是空心的也可以是實心的


四、練習,都是在drawRect方法內操作

1、基本繪圖,使用Path實現

1)獲取與試圖相關聯的上下文對象

//提示:使用Ref聲明的對象,不需要用*

CGContextRef context = UIGraphicsGetCurrentContext();

2)創建及設置路徑(path)

創建路徑

CGMutablePathRef path = CGPathCreateMutable();

設置路徑起點

CGPathMoveToPoint(path, NULL, 50, 50);

增加路徑內容

CGPathAddLineToPoint(path, NULL, 200,200);

CGPathAddLineToPoint(path, NULL, 50, 200);

封閉路徑

CGPathAddLineToPoint(path, NULL, 50, 50);

CGPathCloseSubpath(path);

上面這兩個函數都可以用來封閉路徑,但后者在設置頂點樣式時會使樣式無效

3) 將路徑添加到上下文

CGContextAddPath(context, path);

4)設置上下文狀態

邊線顏色

CGContextSetRGBStrokeColor(context, 0.7, 0.7, 0.5, 1);

填充顏色

CGContextSetRGBFillColor(context, 1, 0, 0, 1);

線寬

CGContextSetLineWidth(context, 10);

設置線條的頂點樣式

CGContextSetLineCap(context, kCGLineCapButt);

設置線條的連接點樣式

CGContextSetLineJoin(context, kCGLineJoinRound);

設置線條的虛線樣式

context

phase 相位,虛線起始的位置,通常使用0即可,從頭開始畫虛線

lengths 長度的數組

count lengths數組的個數

CGFloat lengths[4] = {40.0, 40.0};

CGContextSetLineDash(context, 0.0, lengths, 2);

5)繪制路徑

kCGPathStroke: 畫線(空心)

kCGPathFill:? 填充(實心)

kCGPathFillStroke: 即畫線又填充

CGContextDrawPath(context, kCGPathFillStroke);

6)釋放路徑

CGPathRelease(path);

2、基本繪圖,上下文的默認路徑實現

1)獲取上下文

CGContextRef context = UIGraphicsGetCurrentContext();

2)設置當前上下文的路徑

設置路徑起點

CGContextMoveToPoint(context, 50, 50);

增加路徑內容

CGContextAddLineToPoint(context, 200, 200);

CGContextAddLineToPoint(context, 50, 200);

封閉路徑

CGContextClosePath(context);

CGContextAddLineToPoint(context, 50, 50);

3) 設置上下文狀態

CGContextSetLineWidth(context, 10); //線條寬

CGContextSetLineJoin(context, kCGLineJoinRound); //連接點樣式

CGContextSetLineCap(context, kCGLineCapRound);? //頂點樣式

4)繪制路徑,雖然沒有直接定義路徑,但是第二步操作,就是為上下文指定路徑

CGContextDrawPath(context, kCGPathFillStroke);

3、繪制矩形

CGRect rect = CGRectMake(50, 50, 200, 200);

[[UIColor redColor] setStroke];

[[UIColor grayColor] setFill];

//繪制實心矩形

UIRectFill(rect);

//繪制空心矩形

UIRectFrame(rect);

4、繪制圓形

1. 取出上下文

CGContextRef context = UIGraphicsGetCurrentContext();

2. 設置路徑

CGRect rect = CGRectMake(50, 50, 200, 200);

Ellipse圓形

CGContextAddEllipseInRect(context, rect);

3. 繪制路徑

CGContextDrawPath(context, kCGPathFillStroke);

5、繪制弧度

CGContextRef context = UIGraphicsGetCurrentContext();

context 上下文

x,y 是圓弧所在圓的中心點坐標

radius 半徑,所在圓的半徑

startAngle endAngle 起始角度和截止角度 單位是弧度 M_PI =3.14

0度 對應是圓的最右側點

clockwise 順時針 0 或者逆時針 1

CGContextAddArc(context, 100, 100, 100, 0, M_PI_2, 1);

[[UIColor grayColor] setFill];

CGContextDrawPath(context, kCGPathFill);

6、繪制圖像

UIImage *image = [UIImage imageNamed:@"頭像1.png"];

//提示:繪制之后,就無法改變位置,也沒有辦法監聽手勢識別

在指定點繪制圖像

//[image drawAtPoint:CGPointMake(50, 50)];

//會在指定的矩形中拉伸繪制

[image drawInRect:CGRectMake(0, 0, 320, 460)];

//在指定矩形區域中平鋪圖片

[image drawAsPatternInRect:CGRectMake(0, 0, 320, 460)];

7、繪制文字

NSString *string = @"時間到了反饋結束了的開發就流口水的減肥來看就";

//在指定點繪制文字

[string drawAtPoint:CGPointMake(0, 0) withAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];

//在指定的矩形區域繪制文字

CGRect rect = CGRectMake(50, 50, 210, 360);

[string drawInRect:rect withAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];

提示:如果不在drawRect方法中調用繪圖方法,上下文地址都是0,不能直接進行繪制

8、繪制水印圖片

1. 建立圖像的上下文,需要指定新生成的圖像大小

CGSize imageSize = CGSizeMake(320, 200);

UIGraphicsBeginImageContext(imageSize);

2、繪制圖片

UIImage *image = [UIImage imageNamed:@"NatGeo01.png"];

[image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];

3、繪制矩形

[[UIColor yellowColor]set];

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextAddRect(context, CGRectMake(50, 50, 100, 100));

CGContextDrawPath(context, kCGPathEOFill);

4、添加水印文字

NSString *str = @"我的水印";

[str drawInRect:CGRectMake(0, imageSize.height - 30, imageSize.width - 20, 30)? withAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];

5、獲取到新生成的圖像,從當前上下文獲取到新繪制的圖像

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

6、關閉圖像上下文

UIGraphicsEndImageContext();

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • --繪圖與濾鏡全面解析 概述 在iOS中可以很容易的開發出絢麗的界面效果,一方面得益于成功系統的設計,另一方面得益...
    韓七夏閱讀 2,791評論 2 10
  • Quartz2D以及drawRect的重繪機制字數1487 閱讀21 評論1 喜歡1一、什么是Quartz2D Q...
    PurpleWind閱讀 808評論 0 3
  • 一、Quartz2D基本概念 1、Quartz2D是一個二維圖形繪制引擎,支持iOS環境和Mac OS X環境 ...
    愛攝影的鏟屎官閱讀 345評論 0 1
  • 拖延是個很嚴重而很多人又意識不到的問題,還有一部分人意識到了自己有拖延的毛病,卻又無能為力,我就是這類人之一。因此...
    點滴記錄閱讀 803評論 0 6
  • 生命,生活這種詞語都太過巨大,隨遇而安的不是城市,而是我們自己的心。 其實,對于孟非這個人,我并不熟悉,我不是老南...
    eb9a085b71e6閱讀 315評論 0 0