iOS——Quartz2D(二維圖形繪製)

###一、Quartz2D 基本概述git

  • Core Graphics Framework是一套基於C的API框架,使用了Quartz做爲繪圖引擎。它提供了低級別、輕量級、高保真度的2D渲染。github

  • Quartz 2D是一個二維圖形繪製引擎,適用於iOS和Mac OS X環境,Quartz 2D API能夠不少繪製功能,如基本路徑的繪製、透明度、描影、繪製陰影、透明層、顏色管理、反鋸齒、PDF文檔生成。框架

  • 繪圖上下文Graphics Context是一個數據類型(CGContextRef),用於封裝Quartz繪製圖像到輸出設備的信息。 Quartz中全部的對象都是繪製到一個Graphics Context中。用Quartz繪圖時,能夠簡單地給Quartz繪圖序列指定不一樣的Graphics Context,就可將相同的圖像繪製到不一樣的設備上。咱們不須要任何設備相關的計算,這些都由Quartz替咱們完成。函數

  • Graphics Context定義了基本的繪製屬性,如顏色、裁減區域、線條寬度和樣式信息、字體信息、混合模式等。字體

###二、繪圖方法 在iOS應用程序中,若是要使用 Core Graphics 在屏幕上進行繪製圖像須要在以下方法中進行。代理

  • drawRect:方法 須要建立一個UIView對象,並實現它的drawRect:方法。視圖的drawRect:方法在視圖顯示在屏幕上及它的內容須要更新時被調用,或者使用**setNeedsDisplay**手動調用。
// 1. 將自定義視圖添加到視圖上顯示
- (void)viewDidLoad {
    [super viewDidLoad];
    
    DrawView *drawView = [[DrawView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:drawView];
}
// 2. 在自定義的DrawView 中繪圖,當視圖顯示時就會調用下面的代碼。
- (void)drawRect:(CGRect)rect
{

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextAddRect(ctx, CGRectMake(10, 20, 100, 100));
    CGContextSetFillColorWithColor(ctx, [UIColor grayColor].CGColor);
    CGContextDrawPath(ctx, kCGPathFill);
}
  • drawLayer: inContext:方法 這是CALayer的代理方法,須要設置圖層的代理對象並使用**setNeedsDisplay**方法才能觸發這個方法。
// 1.建立一個layer並設置代理爲當前控制器
- (void)viewDidLoad {
    [super viewDidLoad]; 
    
    CALayer *dLayer = [CALayer layer];
    dLayer.frame = self.view.bounds;
    dLayer.delegate = self;
    [self.view.layer addSublayer:dLayer];  
    [dLayer setNeedsDisplay]; // 調用這個方法才能觸發代理方法繪圖
}
// 2. 在代理方法中繪圖
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{

	// 繪製三角形
    CGContextSetLineWidth(ctx, 2);
    CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
    CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
    CGContextMoveToPoint(ctx, 0, 400);
    CGContextAddLineToPoint(ctx, 320, 400);
    CGContextAddLineToPoint(ctx, 160, 560);
    CGContextAddLineToPoint(ctx, 0, 400);
    CGContextFillPath(ctx);  // 填充
    CGContextStrokePath(ctx); // 描邊
}

###三、Core Graphics上下文函數code

  • 繪圖上下文相關函數對象

    UIGraphicsGetCurrentContext(): 獲取當前繪圖上下文,繪圖前的第一步,由於全部的繪圖都是在上下文完成的,能夠理解爲獲取當前繪圖的「畫布」。圖片

    CGContextSaveGState(): 保存上下文狀態,這個函數的做用是將當前圖形狀態推入堆棧。以後,您對圖形狀態所作的修改會影響隨後的描畫操做,但不影響存儲在堆棧中的拷貝。ip

    CGContextRestoreGState(): 恢復上下文狀態,經過這個函數把堆棧頂部的狀態彈出,返回到以前的圖形狀態。和CGContextSaveGState()配對使用。

    CGContextSaveGState()和CGContextRestoreGState()使用舉例:整個繪圖都是紅色,可是中間須要有個圖是灰色,這種場景就能夠使用這兩個函數處理了。

    // 先設置圖形的填充顏色爲紅色
    	CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
    	// 將以前設置的狀態入棧保存
    	CGContextSaveGState(ctx); 
    	CGContextAddRect(ctx, CGRectMake(10, 20, 100, 100));
    	// 設置中間圖形的填充色修改成灰色
    	CGContextSetFillColorWithColor(ctx, [UIColor grayColor].CGColor);
    	CGContextDrawPath(ctx, kCGPathFillStroke);
    	// 恢復到保存前的繪圖狀態,那麼後面的繪圖就不是灰色了,而是原來的紅色。
    	CGContextRestoreGState(ctx);
  • 繪圖路徑相關函數

    CGContextMoveToPoint(): 定位到某個點

    CGContextAddLineToPoint(): 畫線,添加一條直線到一個點

    CGContextAddRect(): 畫矩形

    CGContextAddEllipseInRect(): 內切圓或者橢圓

    CGContextAddQuadCurveToPoint(): 一個控制點的貝塞爾曲線

    CGContextAddCurveToPoint(): 兩個控制點的貝塞爾曲線

    CGContextAddArc(): 畫曲線

    CGContextSetLineDash(): 畫虛線

    CGContextAddPath(): 畫指定的路勁

    CGContextClosePath(): 閉合當前路徑

  • 繪圖設置相關函數

    CGContextSetLineWidth(): 設置線條的寬度

    CGContextSetStrokeColorWithColor(): 設置線條的顏色(使用UIColor顏色)

    CGContextSetStrokeColor(): 設置線條顏色(三色值和透明度)

    CGContextSetRGBStrokeColor(): 設置線條顏色(RGB值)

    CGContextSetFillColor(): 設置圖形填充顏色(三色值和透明度)

    CGContextSetFillColorWithColor(): 設置填充顏色(UIColor值)

    CGContextSetRGBFillColor():設置填充顏色(RGB值)

    CGContextSetAlaha(): 設置透明度

    CGContextSetShouldAntialias(): 是否開啓抗鋸齒

    CGContextSetLineCap(): 設置直線端點的樣式()

    CGContextSetLineJoin(): 設置直線鏈接點的樣式

    CGContextSetShadow(): 設置陰影(尺寸和模糊度)

    CGContextSetShadowWithColor(): 設置陰影和陰影顏色

  • 圖形填充相關函數

    CGContextFillRect(): 填充一個矩形

    CGContextStrokePath(): 描邊

    CGContextFillPath(): 只填充不描邊

    CGContextEOFillPath(): 使用奇偶規則填充

    CGContextDrawPath(): 繪製路徑(能夠選擇填充的樣式)

###四、使用Core Graphics繪圖

  • 第一步:獲取當前繪圖上下文,至關於建立「畫布」
CGContextRef ctx = UIGraphicsGetCurrentContext();
  • 第二步:設置要繪製的圖形
//直線
    CGContextMoveToPoint(ctx, 100, 250);
    CGContextAddLineToPoint(ctx, 150, 150);
// 矩形
    CGContextAddRect(ctx, CGRectMake(10, 20, 100, 100));
// 內切圓\橢圓
    CGContextAddEllipseInRect(ctx, CGRectMake(120, 20, 100, 100));
// 三角形
    CGContextMoveToPoint(ctx, 0, 400);
    CGContextAddLineToPoint(ctx, 320, 400);
    CGContextAddLineToPoint(ctx, 160, 560);
    CGContextClosePath(ctx);
// 一個控制點的貝塞爾曲線
    CGContextAddQuadCurveToPoint(ctx, 80, 100, 160, 300);
// 兩個控制點的貝塞爾曲線
    CGContextAddCurveToPoint(ctx, 80, 100, 240, 500, 320, 300);
// 弧線
    CGContextAddArc(ctx, 240, 200, 80, 0, M_PI_2, NO);
// 繪製圖片
    CGRect imageFrame = CGRectMake(10, 30, 300, 300);
    // 獲取圖片數據
    NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"png"]; 
    UIImage *img = [UIImage imageWithContentsOfFile:imagePath];
    
    // 設置上下文當前轉換矩陣(CTM),不然圖片倒置
    CGContextTranslateCTM(context, 0, imageFrame.size.height);
    CGContextScaleCTM(context, 1, -1);
    CGContextDrawImage(context, imageFrame, img.CGImage); // 繪製
    // 或者以下繪製,不須要設置CTM
    [img drawInRect:imageFrame];
  • 第三步:設置圖形的屬性(顏色、線條……)
CGContextSetLineWidth(ctx, 5); // 線寬
    CGContextSetFillColorWithColor(ctx, [UIColor blueColor].CGColor); // 填充顏色
    CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor); // 線條顏色
    CGContextSetShouldAntialias(ctx, YES); // 抗鋸齒
    CGContextSetLineCap(ctx, kCGLineCapRound); // 線頭顏色
    CGContextSetLineJoin(ctx, kCGLineJoinBevel); // 連接點樣式
  • 第四步:繪圖(填充)
CGContextFillPath(ctx);    // 填充
    CGContextStrokePath(ctx); // 描邊
    // 或者填充並描邊 
    CGContextDrawPath(ctx, kCGPathFillStroke);

###五、使用UIBezierPath繪圖 UIKit中的UIBezierPath是Core Graphics框架關於path的一個封裝(封裝爲OC的方法)。 使用UIBezierPath繪圖不須要手動獲取繪圖上下文,當drawRect方法被調用時,UIView的繪圖上下文屬於當前圖形上下文。

  • 實例化一個path對象
// 不設置圖形路徑
    UIBezierPath *path = [UIBezierPath bezierPath];
// 矩形路徑
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 100, 200, 200)];
// 內切圓\橢圓路徑
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 100, 200, 200)];
//圓角矩形路徑 
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 100, 200, 200) cornerRadius:20];
// 弧線路徑,ArcCenter:原點、radius:半徑、startAngle:起點弧度、endAngle:終端弧度、clockwise:是否順時針
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:50 startAngle:0 endAngle:M_PI_2 clockwise:YES];
  • 添加路徑
// 移動到某個點
    [path moveToPoint:p1];
	
    // 添加一條線到某個點
    [path addLineToPoint:p2];
	
    // 添加一條貝塞爾曲線
    [path addQuadCurveToPoint:p1 controlPoint:p2];
	
    // 添加一條弧線
    [path addArcWithCenter:p1 radius:50 startAngle:M_PI_4 endAngle:M_PI_2 clockwise:YES];
	
    // 閉合路徑
    [path closePath];	
	
    // 移除全部的點
    [path removeAllPoints];
  • 設置路徑屬性
// 設置填充顏色
    [[UIColor redColor] setFill]; 
	
    // 設置描邊顏色
   [[UIColor whiteColor] setStroke]; 
   	
   // 線寬
    path.lineWidth = 5; 
    
    // 線頭樣式
    path.lineCapStyle = kCGLineCapRound;
    
    // 線鏈接點樣式
    path.lineJoinStyle = kCGLineJoinMiter;
    
    // 鏈接點的斜距(角的內點和外點的距離),鏈接樣式得爲kCGLineJoinMiter
    path.miterLimit = 20;
  • 繪圖(填充)
[path fill];    // 填充
    [path stroke];  // 描邊

###六、實例Demo下載

下載連接:https://github.com/fuqinglin/Quartz2DDemos.git

相關文章
相關標籤/搜索