QuartZ 2D
本demo是由本人通過學習,看前輩們的博客看文檔和自己學習的一個小總結(jié),只用于學習使用,其中難避免有一些錯誤(如果發(fā)現(xiàn)了希望能指正),以及引用一些前輩總結(jié)出來的東西(如果內(nèi)容為禁止引用請指出,小弟馬上刪除),所以此Demo僅供學習參考,不作為權(quán)威學習資料。
適用于:本人自己總結(jié)筆記, 對QuarZ 2D初步了解,作為筆記使用
本Demo只對一般的畫圖形以及基本圖形操作進行一般總結(jié)

目錄
QuartZ2D簡介
QuartZ 2D(Core Graphics)是一個二維繪制引擎,同時支持iOS和Mac系統(tǒng)。它提供低級別、輕量級、高保真的2D渲染。該框架可以用于基于路徑的繪圖、變換、顏色管理、脫貧渲染、模板、漸變。
可以完成的工作
- 繪制圖形:線條\三角形\矩形\圓\弧 等
- 繪制文字
- 繪制\生成圖片
- 讀取\生成PDF
- 截圖\裁剪圖片
QuartZ2D開發(fā)中的作用
- 繪制一些系統(tǒng)沒有的圖形,比如折線圖
- 自定義控件
圖形上下文
圖形上下文(CGContextRef)相當于畫板,用于分鐘繪畫信息繪畫狀態(tài)和輸出。
類型
- Bitmap Graphics Context
- PDF Graphics Context
- Window Graphics Context
- Layer Context
- Post Graphics Context
DrawRect
UIView的顯示
UIView的顯示過程
1.當UIView需要顯示時,內(nèi)部的層會準備好一個CGConextRef(圖形上下文)然后調(diào)用delegate(這里就是UIView)的drawLayer:inContext:方法,并且傳入已經(jīng)準備好的CGContextRef對象。而UIView在drawLayer:inContext:方法中又會調(diào)用自己的drawRect:方法
2平時在drawRect:中通過UIGraphicsGetCurrentContext()獲取的就是由層傳入的CGContextRef對象,在drawRect:中完成的所有繪圖都會填入層的CGContextRef中,然后被拷貝至屏幕
UIView的顯示原理
1既使不導入QuartzCore框架,NSObject和UIView類中的-drawLayer:inContext:方法,也是存在的,只是沒有代碼提示而已.
2默認情況下,根圖層的delegate就是根圖層所在的UIView對象,只不過是弱引用.
@property(assign) id delegate;
3當UIView需要顯示時,它內(nèi)部的view.layer圖層會準備好一個CGContextRef關(guān)聯(lián)到圖層設備,然后調(diào)用view.layer.delegate代理(就是view)的(原生的)-drawLayer:inContext:方法.
繪圖步驟
直接繪畫
1.獲取當前控件圖形上下文
2.描述繪畫內(nèi)容
3.設置繪畫上下文狀態(tài)
4.渲染圖形上下文
// 1.獲取圖形上下文
CGContextRef context = UIGraphicsGetCurrentContext();
// 2.直接繪制內(nèi)容
CGContextMoveToPoint(context, 50, 50); // 移動到一個點
CGContextAddLineToPoint(context, 200, 50); // 畫直線
//3. 設置屬性
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); // 設置畫筆顏色
CGContextSetLineWidth(context, 5); // 設置線寬
// 4.渲染
CGContextStrokePath(context);

通過添加路徑(等)繪制
1.獲取當前控件圖形上下文
2.創(chuàng)建路徑,描繪路徑(CGPath, UIBezierPath)
3.把路徑添加到上下文中
4.設置上下文狀態(tài)
5.渲染上下文
// 1.獲取當前山下文
CGContextRef context = UIGraphicsGetCurrentContext();
// 2.創(chuàng)建路徑,描繪路徑
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 10, 50); //移動到(10, 50)
CGPathAddLineToPoint(path, NULL, 300, 50); //畫一條直線到(300, 50)
CGPathMoveToPoint(path, NULL, 10, 80); //移動到(10, 80)
CGPathAddLineToPoint(path, NULL, 300, 80); //畫一條直線到(300, 80)
CGPathAddRect(path, NULL, CGRectMake(10, 100, 200, 200)); //畫一個矩形(10, 100, 200, 200)
//3.把路徑添加到上下文中
CGContextAddPath(context, path);
//4.設置上下文狀態(tài)
[[UIColor redColor] set]; // 設置顏色
CGContextSetLineWidth(context, 10); //設置線寬
CGContextSetLineCap(context, kCGLineCapRound); //設置線終點樣式
CGContextSetLineJoin(context, kCGLineJoinRound);//設置線拐角樣式
//5.渲染
CGContextStrokePath(context);
//釋放CGMutablePathRef
CGPathRelease(path);

通過UIBezierPath繪圖
提示:
1.UIKit已經(jīng)封裝了一些繪圖的功能:UIBezierPath,里面封裝了很多東西,可以幫我畫一些基本的線段,矩形,圓等等,一般開發(fā)中用貝塞爾路徑繪圖。
2.CGPath轉(zhuǎn)換:UIKit框架轉(zhuǎn)CoreGraphics直接 .CGPath 就能轉(zhuǎn)換
繪制過程:
1.創(chuàng)建Bezier路徑
2.繪制bezier路徑
3.設置bezier狀態(tài)
4.繪制路徑
//1.獲取UIBezierPath
UIBezierPath *path = [UIBezierPath bezierPath];
//2. 畫一個圓 參數(shù)分別是: 圓心,半徑,開始弧度,結(jié)束弧度,順時針
[path addArcWithCenter:self.center radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
//3.設置狀態(tài)
[[UIColor blueColor] set]; //設置顏色
[path setLineWidth:5]; //設置線寬
//4.渲染
[path stroke];

畫圖形
直線
// 獲取行下文
CGContextRef context = UIGraphicsGetCurrentContext();
float width = self.bounds.size.width; //寬度
float heiht = self.bounds.size.height; //高度
float distance = 40; //間距
float beginY = 10; //開始的Y坐標
float beginX = 10; //開始的X坐標
//橫線
NSInteger countOfX = (heiht - beginY)/distance;
for(NSInteger index = 0; index <= countOfX; index ++){
float Y = beginY + index * distance;
CGPoint begin = CGPointMake(beginX, Y);
CGPoint end = CGPointMake(width, Y);
CGContextMoveToPoint(context, begin.x, begin.y);
CGContextAddLineToPoint(context, end.x, end.y);
}
//豎線
NSInteger countOfY = (width - beginX)/distance;
for(NSInteger index = 0; index <= countOfY; index ++){
float X = beginX + index * distance;
CGPoint begin = CGPointMake(X, beginY);
CGPoint end = CGPointMake(X, heiht);
CGContextMoveToPoint(context, begin.x, begin.y);
CGContextAddLineToPoint(context, end.x, end.y);
}
// 設置屬性
[[UIColor blueColor] set];
CGContextSetLineWidth(context, 0.5);
// 渲染
CGContextStrokePath(context);

三角形
// 三角形的三個點
CGPoint point1 = CGPointMake(160, 100);
CGPoint point2 = CGPointMake(10, 300);
CGPoint point3 = CGPointMake(320, 300);
// 繪制點
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:point1];
[path addLineToPoint:point2];
[path addLineToPoint:point3];
[path addLineToPoint:point1];
// 設置樣式
[[UIColor redColor] set];
[path setLineWidth:10];
[path setLineJoinStyle:kCGLineJoinRound];
// 渲染
[path stroke];

矩形
//1.獲取上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//2.畫第一個矩形
CGContextAddRect(context, CGRectMake(50, 50, 100, 100));
[UIColor redColor];
CGContextStrokePath(context);
//3.畫第二個矩形
CGContextAddRect(context, CGRectMake(50, 200, 200, 200));
[[UIColor blueColor] set];
CGContextSetLineWidth(context, 5);
CGContextStrokePath(context);

橢圓
//1.獲取上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//第一個橢圓(圓)
CGContextAddEllipseInRect(context, CGRectMake(50, 50, 200, 200));
[[UIColor redColor] set];
CGContextSetLineWidth(context, 5);
CGContextStrokePath(context);
//第二個圓(橢圓)
CGContextAddEllipseInRect(context, CGRectMake(50, 300, 300, 200));
[[UIColor blueColor] set];
CGContextSetLineWidth(context, 10);
CGContextStrokePath(context);

圓弧
CGContextRef context = UIGraphicsGetCurrentContext();
// 參數(shù)依次是: 上下文,圓心x, 圓心y, 半徑, 開始弧度, 結(jié)束弧度, 逆時針方向
CGContextAddArc(context, 200, 200, 90, M_PI_2, M_PI, YES);
CGContextStrokePath(context);
//第二個圓弧
CGContextMoveToPoint(context, 200, 400);
CGContextAddArc(context, 200, 400, 90, 0, M_PI_2, YES);
CGContextAddLineToPoint(context, 200, 400);
[[UIColor grayColor] set];
CGContextFillPath(context);

曲線
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(0, 200)];
//第一段曲線 參數(shù):到的點,控制點(具體查看賽貝爾線)
[path addQuadCurveToPoint:CGPointMake(self.bounds.size.width * 0.5, 200) controlPoint:CGPointMake(self.bounds.size.width * 0.25, 150)];
//第二段曲線
[path addQuadCurveToPoint:CGPointMake(self.bounds.size.width, 200) controlPoint:CGPointMake(self.bounds.size.width * 0.75, 250)];
[[UIColor redColor] set];
[path setLineWidth:2];
[path stroke];

圖片處理
水印
/** 圖片加水印 */
+ (UIImage *)imageName:(NSString *)imageName logoImageName:(NSString *)logoImageName {
UIImage *image = [UIImage imageNamed:imageName];
// 開始Image上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
//畫主圖
[image drawAtPoint:CGPointZero]; //
//畫log圖
UIImage *logoImage = [UIImage imageNamed:logoImageName];
[logoImage drawInRect:CGRectMake(image.size.width - 100, image.size.height - 100, 100, 100)];
//獲取合成圖
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndPDFContext();
return newImage;
}

剪切
/** 圖片剪切 */
+ (UIImage *)imageClip:(NSString *)imageName {
UIImage *image = [UIImage imageNamed:imageName];
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
//剪切
UIBezierPath *path = [UIBezierPath bezierPath];
[path addArcWithCenter:CGPointMake(image.size.width * 0.5, image.size.height * 0.5) radius:image.size.width * 0.5 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
[path addClip];
// 畫圖
[image drawAtPoint:CGPointZero];
// 獲取新圖片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
