Quartz2D

一、Quartz2D概述

Quartz2D是一个二维绘图引擎,同时支持Mac和iOS系统

Quartz2D能绘制图形、绘制文字、绘制图片、生成PDF、裁剪图片等,还可以用来自定义UI控件。

例如画板应用、手势解锁功能、图形报表等都是用Quartz2D实现的。

1. 图形上下文(Graphics Context)

图形上下文(Graphics Context)是一个CGContextRef类型的数据,它用来保存绘图信息、绘图状态和决定绘制的输出目标(输出目标可以是PDF文件、Bitmap或者显示器的窗口上)。

相同的一套绘图序列,指定不同的图形上下文可将相同的图像绘制到不同的目标上。

Quartz2D提供了一下几种类型的Graphics Context:

  • Bitmap Graphics Context
  • PDF Graphics Context
  • Window Graphics Context
  • Layer Graphics Context
  • Printer Graphics Context

2. drawRect:方法

当view第一次显示到屏幕上时(被加到UIWindow上显示出来)就会调用drawRect:,调用view的setNeedDisplay或者setNeedDisplayInRect:时也会调用drawRect:

3. drawRect:中取得上下文

在drawRect:方法中取得上下文后,就可以绘制图形到view上面了。view内部有个layer属性,drawRect:方法中取得的是一个Layer Graphics Context,因此绘制的图形其实是绘制到view的layer上去了。

view之所以能显示东西,是因为它内部有layer。

4. Quartz2D的内存管理

使用含有“Create”或“Copy”的函数创建的对象,使用完后必须释放,否则将导致内存泄露,使用不含“Create”或“Copy”的函数获取的对象,则不需要释放。

如果retain了一个对象,不再使用时也需要将其release掉。

可以使用Quartz2D的函数来指定retain和release一个对象,例如,如果创建了一个CGColorSpace对象,则使用函数CGColorSpaceRetain和CGColorSpaceRelease来retain和release对象。

也可以使用Core Foundation的CFRetain和CFRelease。注意不能传递NULL值给这些函数。

 

二、代码

1. 画三角形

 1 /**
 2  *  画三角形
 3  */
 4 void drawTriangle()
 5 {
 6     // 1.获得图形上下文
 7     CGContextRef contextRef = UIGraphicsGetCurrentContext();
 8     
 9     // 2.拼接图形路径
10     // 设置一个起点
11     CGContextMoveToPoint(contextRef, 100, 100);
12     // 添加一条线段到(100,100)
13     CGContextAddLineToPoint(contextRef, 200, 200);
14     // 添加一条线段到(150,40)
15     CGContextAddLineToPoint(contextRef, 150, 40);
16     // 关闭路径(连接起点和终点)
17     CGContextClosePath(contextRef);
18     
19     // 3.渲染显示到View上面
20     CGContextStrokePath(contextRef);
21 }

2. 画矩形

 1 /**
 2  *  画四边形
 3  */
 4 void drawQuadrilateral()
 5 {
 6     // 1.获得图形上下文
 7     CGContextRef contextRef = UIGraphicsGetCurrentContext();
 8     // 2.画矩形
 9     CGContextAddRect(contextRef, CGRectMake(100, 100, 150, 100));
10     // 3.绘制图形
11     CGContextStrokePath(contextRef);
12 }

3. 画圆

 1 /**
 2  *  画圆
 3  */
 4 void drawCircle()
 5 {
 6     // 1.获得图形上下文
 7     CGContextRef contextRef = UIGraphicsGetCurrentContext();
 8     // 2.画圆
 9     CGContextAddEllipseInRect(contextRef, CGRectMake(100, 100, 100, 100));
10     // 3.绘制图形
11     CGContextFillPath(contextRef);
12 }

4. 画圆弧

 1 /**
 2  *  画圆弧
 3  */
 4 void drawArc()
 5 {
 6     // 1.获得图形上下文
 7     CGContextRef contextRef = UIGraphicsGetCurrentContext();
 8     
 9     // 2.画圆弧
10     // x\y : 圆心坐标
11     // radius : 半径
12     // startAngle : 开始角度
13     // endAngle : 结束角度
14     // clockwise : 圆弧的伸展方向(0:顺时针, 1:逆时针)
15     CGContextAddArc(contextRef, 100, 100, 50, 0, M_PI, 1);
16     
17     // 3.绘制图形
18     CGContextStrokePath(contextRef);
19 }

5. 画文字

 1 /**
 2  *  画文字
 3  */
 4 void drawText()
 5 {
 6     NSString *str = @"画文字";
 7     // 设置文字属性
 8     NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
 9     attrs[NSForegroundColorAttributeName] = [UIColor redColor];
10     attrs[NSFontAttributeName] = [UIFont systemFontOfSize:20];
11     
12     // 将文字画在某个位置
13     [str drawAtPoint:CGPointMake(100, 100) withAttributes:attrs];
14     
15     // 将文字画在矩形框内
16 //    [str drawInRect:CGRectMake(100, 100, 100, 100) withAttributes:attrs];
17 }

6. 画图片

1 /**
2  *  画图片
3  */
4 void drawImage()
5 {
6     UIImage *image = [UIImage imageNamed:@"1.jpg"];
7     [image drawAsPatternInRect:CGRectMake(100, 100, 100, 100)];
8 }

7. 图形上下文栈

 1 /**
 2  *  图形上下文栈
 3  */
 4 void ContextSaveGState()
 5 {
 6     // 获得图形上下文
 7     CGContextRef contextRef = UIGraphicsGetCurrentContext();
 8     
 9     // 将contextRef拷贝一份放到栈中
10     CGContextSaveGState(contextRef);
11     
12     // 设置绘图状态
13     CGContextSetLineWidth(contextRef, 10);
14     [[UIColor redColor] set];
15     CGContextSetLineCap(contextRef, kCGLineCapRound);
16     
17     // 第一根线
18     CGContextMoveToPoint(contextRef, 50, 50);
19     CGContextAddLineToPoint(contextRef, 120, 190);
20     
21     // 画线
22     CGContextStrokePath(contextRef);
23     
24     // 将栈顶的上下文出栈,替换当前的上下文
25     CGContextRestoreGState(contextRef);
26     
27     // 第二根线
28     CGContextMoveToPoint(contextRef, 10, 70);
29     CGContextAddLineToPoint(contextRef, 220, 290);
30     
31     // 画线
32     CGContextStrokePath(contextRef);
33 }

8. 矩阵操作(图形整体缩放、移动、旋转等等)

 1 /**
 2  *  矩阵操作
 3  */
 4 void contextMatrix()
 5 {
 6     // 获得图形上下文
 7     CGContextRef contextRef = UIGraphicsGetCurrentContext();
 8     
 9     // 缩小0.5倍(在画线条之前设置)
10     CGContextScaleCTM(contextRef, 0.5, 0.5);
11     // 旋转
12     CGContextRotateCTM(contextRef, M_PI_4);
13     // 移动
14     CGContextTranslateCTM(contextRef, 0, 150);
15     
16     // 画矩形
17     CGContextAddRect(contextRef, CGRectMake(100, 100, 100, 100));
18     CGContextStrokePath(contextRef);
19 }

9. 图片裁剪

 1 /**
 2  *  图片裁剪
 3  */
 4 - (void)imageClip
 5 {
 6     // 1.加载原图
 7     UIImage *oldImage = [UIImage imageNamed:@"1.jpg"];
 8     // 2.开启上下文
 9     UIGraphicsBeginImageContextWithOptions(oldImage.size, NO, 0.0);
10     // 3.取得当前的上下文
11     CGContextRef contextRef = UIGraphicsGetCurrentContext();
12     // 4.画圆
13     CGRect circleRect = CGRectMake(0, 0, oldImage.size.width, oldImage.size.height);
14     CGContextAddEllipseInRect(contextRef, circleRect);
15     // 5.按照当前的路径形状(圆形)裁剪,超出这个形状以外的内容都不显示
16     CGContextClip(contextRef);
17     // 6.画图
18     [oldImage drawInRect:circleRect];
19     // 7.取图
20     UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
21     // 8.结束
22     UIGraphicsEndImageContext();
23 }

10. 截屏

 1 /**
 2  *  截屏
 3  */
 4 - (void)screenCut
 5 {
 6     // 1.开启上下文
 7     UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, 0.0);
 8     // 2.将控制器view的layer渲染到上下文
 9     [self.layer renderInContext:UIGraphicsGetCurrentContext()];
10     // 3.取出图片
11     UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
12     // 4.结束上下文
13     UIGraphicsEndImageContext();
14 }

11. 重绘

1 /**
2  *  重绘
3  */
4 - (void)reDraw
5 {
6     // 重绘(这个方法内部会重新调用drawRect:方法进行绘制)
7     [self setNeedsDisplay];
8 }

12. 常用属性

 1 /**
 2  *  常用属性
 3  */
 4 void ContextProperty()
 5 {
 6     // 获得图形上下文
 7     CGContextRef contextRef = UIGraphicsGetCurrentContext();
 8     
 9     // 设置线段宽度
10     CGContextSetLineWidth(contextRef, 10);
11     // 设置颜色
12     CGContextSetRGBStrokeColor(contextRef, 1, 0, 0, 1);
13     // 设置线段头尾部样式
14     CGContextSetLineCap(contextRef, kCGLineCapRound);
15     // 设置线段转折点的样式
16     CGContextSetLineJoin(contextRef, kCGLineJoinRound);
17     // set : 同时设置为实心和空心颜色
18     // setStroke : 设置空心颜色
19     // setFill : 设置实心颜色
20     [[UIColor whiteColor] set];
21     
22     // 裁剪,裁剪后所画内容只能在裁剪的范围内显示
23     CGContextClip(contextRef);
24 }

 

posted @ 2015-09-21 13:59  骑着蜗牛看雪  阅读(350)  评论(0编辑  收藏  举报