Quartz2D--iOS下的图形绘制

时间:2023-01-17 22:17:21

一、基本介绍

Quartz 2D是一个二维绘图引擎,Quartz 2DAPIC语言,来自CoreGraphics框架,没有面向对象的思想。

 1.作用:绘制图形:线条、三角形、矩形、圆、弧等

 绘制文字

 绘制、生成图片(图形)

 读取、生成PDF

 截图、裁剪图片

 自定义UI控件

 2.图形上下文(Graphics Context:是一个CGContextRef类型的数据

 

 图形上下文的作用:1.保存绘图信息、绘图状态

 2.决定绘制的输出目标(绘制到什么地方,输出目标可以是PDF文件、Bitmap或者显示器的窗口上)

 

二、Quartz 2D基本图形绘制

1.线段、矩形、三角形的绘制

新建工程,新建 DrawLine 类继承UIView,在storyboard拖拽一个View,关联DrawLine类,在DrawLine中实现图形绘制代码

 

  1 #import "DrawLine.h"
  2 
  3 @implementation DrawLine
  4 
  5 
  6 // Only override drawRect: if you perform custom drawing.
  7 // An empty implementation adversely affects performance during animation.
  8 
  9 
 10 //系统自动调用 drawRect 方法,当视图显示在屏幕上的时候调用,并且只会被调用一次
 11 //而当它的内容需要更新的时候,也会被调用,那个调用需要通过setNeedsDisplayInRect
 12 - (void)drawRect:(CGRect)rect {
 13 
 14     //画一条线段
 15     drawline();
 16     
 17     //画两条线段
 18     drawline2();
 19     
 20     //画矩形
 21     drawR();
 22     
 23     //画三角形
 24     drawTriangle();
 25     
 26 }
 27 
 28 
 29 /** Quartz 2D的API是C语言,所以要用C的ff */
 30 
 31 //画线
 32 
 33 //画一条线段
 34 void drawline(){
 35     //1.获得图形上下文
 36     CGContextRef context = UIGraphicsGetCurrentContext();
 37     
 38     //2.绘制图形
 39     
 40     //2.1 设置线段的宽度
 41     //参数1:图形上下文
 42     //参数2:宽度
 43     CGContextSetLineWidth(context, 10);
 44     
 45     //2.2 设置线条的颜色
 46     //空心的颜色
 47     CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
 48     
 49     //2.3 设置起点
 50     //参数1:图形上下文
 51     //参数2:起点x坐标
 52     //参数3:起点y坐标
 53     CGContextMoveToPoint(context, 10, 10);
 54     
 55     //画线(添加线条)
 56     CGContextAddLineToPoint(context, 100, 100);
 57     
 58     //3.将绘制的图形显示到View上
 59     //以空心的方式画出
 60     CGContextStrokePath(context);
 61 }
 62 
 63 //画两条线段
 64 void drawline2(){
 65     //获得图形上下文
 66     CGContextRef context = UIGraphicsGetCurrentContext();
 67     
 68     //设置线段的宽度
 69     //参数1:图形上下文
 70     //参数2:宽度
 71     CGContextSetLineWidth(context, 10);
 72 
 73     
 74     //2条线条
 75     [[UIColor blueColor] set];
 76     
 77     //设置线条头尾部的样式
 78     //参数2:头尾部的样式
 79     //kCGLineCapButt,线条头尾部比较大
 80     //kCGLineCapRound,线条头尾部圆形
 81     //kCGLineCapSquare,线条头尾部是方形
 82     CGContextSetLineCap(context, kCGLineCapRound);
 83     
 84     //设置线段转折点样式
 85     //参数2:转折点样式
 86     //kCGLineJoinMiter,
 87     //kCGLineJoinRound,
 88     //kCGLineJoinBevel
 89     CGContextSetLineJoin(context, kCGLineJoinRound);
 90     
 91     //设置起点
 92     CGContextMoveToPoint(context, 100, 100);
 93     //画线(添加线条)
 94     CGContextAddLineToPoint(context, 150, 120);
 95     CGContextAddLineToPoint(context, 150, 180);
 96     CGContextStrokePath(context);
 97 }
 98 
 99 //画矩形,系统提供了方法
100 void drawR(){
101     //1.获得图形上下文
102     CGContextRef context = UIGraphicsGetCurrentContext();
103     
104     //2.绘制四边形
105     //参数1:图形上下文
106     //参数2:CGRect rect
107     CGContextAddRect(context,  CGRectMake(200, 30, 120, 180));//这个系统提供的绘制四边形的方法,四边形的边会与x,y轴平行。我们可以通过旋转View,或者用CGContextAddLineToPoint方法自定义
108     
109     //设置颜色
110     [[UIColor purpleColor] setFill];//实心颜色
111     
112     //3.显示在View上
113     CGContextFillPath(context);//实心图案
114 }
115 
116 
117 //画三角形
118 void drawTriangle(){
119     //1.获取图形上下文
120     CGContextRef context = UIGraphicsGetCurrentContext();
121     
122     //2.绘制三角形
123     //确定起点
124     CGContextMoveToPoint(context, 0, 0);
125     //添加线条
126     CGContextAddLineToPoint(context, 100, 100);
127     CGContextAddLineToPoint(context, 150, 100);
128     
129     //调用系统提供的方法关闭路径
130     CGContextClosePath(context);
131     
132     //设置一下颜色
133     [[UIColor yellowColor] set];
134     
135     //显示到view上
136     CGContextStrokePath(context);
137     
138 }
139 
140 
141 @end

 

以上代码输出样式:

Quartz2D--iOS下的图形绘制

 

 

另外利用图形上下文栈,可以控制线条的样式,代码如下:

 1 //画一条线段
 2 void drawline(){
 3     //1.获得图形上下文
 4     CGContextRef context = UIGraphicsGetCurrentContext();
 5     
 6     //将上下文拷贝一份放到栈中
 7     CGContextSaveGState(context);
 8     
 9     //2.绘制图形
10     //第1条线
11     //2.1 设置线段的宽度
12     //参数1:图形上下文
13     //参数2:宽度
14     CGContextSetLineWidth(context, 20);
15     
16     //设置线条头尾部的样式
17     CGContextSetLineCap(context, kCGLineCapRound);
18     
19     //2.2 设置线条的颜色
20     //空心的颜色
21     CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
22     
23     //2.3 设置起点
24     //参数1:图形上下文
25     //参数2:起点x坐标
26     //参数3:起点y坐标
27     CGContextMoveToPoint(context, 10, 10);
28     
29     //画线(添加线条)
30     CGContextAddLineToPoint(context, 100, 100);
31     
32     //3.将绘制的图形显示到View上
33     //以空心的方式画出
34     CGContextStrokePath(context);
35     
36     //将图形上下文出栈,替换当前的上下文
37     CGContextRestoreGState(context);
38     
39     //2条线条
40     [[UIColor blueColor] set];
41     
42     //设置线条头尾部的样式
43     //参数2:头尾部的样式
44     //kCGLineCapButt,线条头尾部比较大
45     //kCGLineCapRound,线条头尾部圆形
46     //kCGLineCapSquare,线条头尾部是方形
47     CGContextSetLineCap(context, kCGLineCapRound);
48     
49     //设置线段转折点样式
50     //参数2:转折点样式
51     //kCGLineJoinMiter,
52     //kCGLineJoinRound,
53     //kCGLineJoinBevel
54     CGContextSetLineJoin(context, kCGLineJoinRound);
55     
56     //设置起点
57     CGContextMoveToPoint(context, 120, 120);
58     //画线(添加线条)
59     CGContextAddLineToPoint(context, 150, 120);
60     CGContextAddLineToPoint(context, 150, 180);
61     CGContextStrokePath(context);
62 }

图片效果:

Quartz2D--iOS下的图形绘制

 

 

 

 

 

 

2.圆形、弧形、文字、图片的绘制

新建一个类 DrawCircle 继承 UIView ,把storyboard里的View关联该类,然后实现代码

 

  1 #import "DrawCircle.h"
  2 
  3 //求弧度的方法
  4 CGFloat arc(CGFloat angle){
  5     return angle * (M_PI / 180);
  6 }
  7 
  8 @implementation DrawCircle
  9 
 10 
 11 - (void)drawRect:(CGRect)rect {
 12 
 13     //圆形
 14     drawCircle();
 15     
 16     //画圆弧
 17     drawArc();
 18     
 19     //文字
 20     drawText();
 21     
 22     //图片
 23     //绘制图片
 24     drawImg();
 25 }
 26 
 27 //圆形
 28 void drawCircle(){
 29     //1.获取图形上下文
 30     CGContextRef context = UIGraphicsGetCurrentContext();
 31     
 32     //2.绘制图形
 33     //系统画椭圆的方法,如果把宽度和高度设为一样就是圆形了
 34     //参数1:图形上下文
 35     //参数2:CGRect rect
 36     CGContextAddEllipseInRect(context, CGRectMake(50, 50, 80, 100));
 37     //设置线条的宽度
 38     CGContextSetLineWidth(context, 5);
 39     //3.显示在View上
 40     CGContextStrokePath(context);
 41     
 42 }
 43 
 44 //弧形
 45 void drawArc(){
 46     //1.获取图形上下文
 47     CGContextRef context = UIGraphicsGetCurrentContext();
 48     
 49     //2.绘制图形
 50     //系统提供画圆弧的方法
 51     //参数1:图形上下文
 52     //参数2:圆心所在的x坐标
 53     //参数3:圆心所在的y坐标
 54     //参数4:半径
 55     //参数5:开始的角度
 56     //参数6:结束的角度
 57     //参数7:旋转方向,1-->顺时针,0-->逆时针
 58     CGContextAddArc(context, 150, 150, 50, arc(0), arc(90), 0);
 59     
 60     //3.显示
 61     CGContextFillPath(context);
 62 }
 63 
 64 //绘制文字
 65 void drawText(){
 66     
 67     NSString * str = @"绘制文字";
 68     
 69     NSMutableDictionary * attributes = [NSMutableDictionary dictionary];
 70     attributes[NSFontAttributeName] = [UIFont systemFontOfSize:20];//设置文字大小
 71     attributes[NSForegroundColorAttributeName] = [UIColor purpleColor];//设置文字的颜色
 72    
 73     //在这里中,绘制文字的方法是直接调用OC中的方法,所以不需要获得图形上下文,直接调用
 74     //参数1:文字的位置和宽高
 75     //参数2:字典
 76     [str drawInRect:CGRectMake(200, 100, 100, 100) withAttributes:attributes];
 77 
 78 }
 79 
 80 //绘制图片
 81 void drawImg(){
 82     //1.因为绘制图片也是调用OC的方法,所以不需要拿到图形上下文,只需要拿到图片即可
 83     //取得图片
 84     UIImage * img = [UIImage imageNamed:@"广州.png"];
 85     
 86     //2.画图片
 87     [img drawAtPoint:CGPointMake(5, 300)];//在哪个点画图片
 88     
 89     //3.该方法规定了图片的高度和宽度
 90 //    img drawInRect:CGRectMake(<#CGFloat x#>, <#CGFloat y#>, <#CGFloat width#>, <#CGFloat height#>)
 91     
 92     //4.这个方法规定了 按图片高度和宽度来使用填充
 93 //    img drawAsPatternInRect:CGRectMake(<#CGFloat x#>, <#CGFloat y#>, <#CGFloat width#>, <#CGFloat height#>)
 94     
 95     //在图片上绘制文字,即水印
 96     NSString * str = @"广州";
 97     [str drawInRect:CGRectMake(10, 300, 100, 40) withAttributes:nil];
 98 }
 99 
100 
101 
102 @end

运行效果:

Quartz2D--iOS下的图形绘制

 

3.补充:贝塞尔曲线

贝塞尔曲线:是由线段和节点构成的,它的节点是可以移动的,线段就像橡皮筋一样随着节点和变化

示例代码:

 1 //贝塞尔曲线:是由线段和节点构成的,它的节点是可以移动的,线段就像橡皮筋一样随着节点和变化
 2 void drawBezier(){
 3     //1.取得图形上下文
 4     CGContextRef context = UIGraphicsGetCurrentContext();
 5     
 6     //贝塞尔曲线有四个节点,一个起点,一个终点,还有两个控制点
 7     
 8     //设置起点
 9     CGContextMoveToPoint(context, 10, 10);
10     
11     //添加2个控制点
12     //参数1:图形上下文
13     //参数2:第一个控制点的x坐标
14     //参数3:第一个控制点的y坐标
15     //参数4:第二个控制点的x坐标
16     //参数5:第二个控制点的y坐标
17     //参数6:终点的x坐标
18     //参数7:终点的y坐标
19     CGContextAddCurveToPoint(context, 120, 100, 180, 50, 190, 190);
20     
21     //系统中还有一个方法添加1个控制点
22     //参数1:图形上下文
23     //参数2:第一个控制点的x坐标
24     //参数3:第一个控制点的y坐标
25     //参数4:终点的x坐标
26     //参数5:终点的y坐标
27 //    CGContextAddQuadCurveToPoint(context, 150, 200, 200, 100);
28     
29     //显示到View上
30     CGContextStrokePath(context);
31 }

运行效果:

Quartz2D--iOS下的图形绘制

 

三、使用Quartz 2D绘制小黄人

在storyboard中的View关联创建的 DrawHuman 类,实现代码

  1 #import "DrawHuman.h"
  2 
  3 //半径
  4 #define JKRadius 70
  5 //Y坐标
  6 #define JKTopY 100
  7 //颜色
  8 #define JKColor(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
  9 
 10 @implementation DrawHuman
 11 
 12 
 13 // Only override drawRect: if you perform custom drawing.
 14 // An empty implementation adversely affects performance during animation.
 15 - (void)drawRect:(CGRect)rect {
 16 
 17     //1.图形上下文
 18     CGContextRef context = UIGraphicsGetCurrentContext();
 19     
 20     //画身体
 21     drawBody(context,rect);
 22     
 23     //画嘴巴
 24     drawMouse(context,rect);
 25     
 26     //画眼睛
 27     drawEyes(context,rect);
 28 }
 29 
 30 //画身体
 31 void drawBody(CGContextRef context,CGRect rect){
 32     //1.上半圆的画法
 33     CGFloat topX = rect.size.width * 0.5;
 34     CGFloat topY = JKTopY;
 35     CGFloat topRadius = JKRadius;
 36     //圆心坐标,topX,topY
 37     //半径,topRadius
 38     //开始角度,0
 39     //结束角度,M_PI
 40     //方向,1顺时针
 41     CGContextAddArc(context, topX, topY, topRadius, 0, M_PI , 1);
 42     
 43 
 44     //2.向下延伸 的直线
 45     CGFloat middleX = topX - topRadius;//向下延伸的X坐标
 46     CGFloat middleH = JKTopY;//向下延伸的高度
 47     CGFloat middleY = JKTopY + 100;//Y轴的高度
 48     //添加一条直线
 49     CGContextAddLineToPoint(context, middleX, middleY);
 50     
 51 
 52     //3.下半圆
 53     CGFloat bottomX = topX;
 54     CGFloat bottomY = middleY;
 55     CGFloat bottomRadius = topRadius;
 56     CGContextAddArc(context, bottomX, bottomY, bottomRadius, M_PI, 0, 1);
 57     
 58     //合并路径
 59     CGContextClosePath(context);
 60 
 61     
 62     //设置颜色
 63     [JKColor(252,218,0) set];
 64     
 65     //显示在View上
 66     CGContextFillPath(context);
 67 }
 68 
 69 //画嘴巴
 70 void drawMouse(CGContextRef context,CGRect rect){
 71     //设置一个控制点
 72     CGFloat controlX = rect.size.width * 0.5;
 73     CGFloat controlY = rect.size.height * 0.3;
 74     
 75     //设置当前点
 76     // x y 轴的距离
 77     CGFloat marginX = 20;
 78     CGFloat marginY = 10;
 79     //当前点,即贝塞尔曲线的起点位置
 80     CGFloat currentX = controlX - marginX;
 81     CGFloat currentY = controlY - marginY;
 82     CGContextMoveToPoint(context, currentX, currentY);
 83     
 84     //结束点
 85     CGFloat endX = controlX + marginX;
 86     CGFloat endY = currentY;
 87     
 88     //贝塞尔曲线
 89     CGContextAddQuadCurveToPoint(context, controlX, controlY, endX, endY);
 90     
 91     //设置颜色
 92     [[UIColor blackColor] set];
 93     
 94     //显示到View上
 95     CGContextStrokePath(context);
 96 }
 97 
 98 //画眼睛
 99 void drawEyes(CGContextRef context,CGRect rect){
100     
101     //1.黑色绑带
102     CGFloat startX = rect.size.width * 0.5 - JKRadius;
103     CGFloat startY = JKTopY;
104     //将线段移动到起点
105     CGContextMoveToPoint(context, startX, startY);
106     
107     //设置终点的值
108     CGFloat endx = startX + 2*JKRadius;
109     CGFloat endY = JKTopY;
110     
111     //画线
112     CGContextAddLineToPoint(context, endx, endY);
113     CGContextSetLineWidth(context, 15);
114     [[UIColor blackColor] set];
115     
116     //显示到View上
117     CGContextStrokePath(context);
118     
119     //灰色镜框
120     [JKColor(61,62,66) set];
121     CGFloat kuangRadius = JKRadius * 0.4;
122     CGFloat kuangY = startY;
123     CGFloat kuangX = rect.size.width * 0.5 - kuangRadius;
124     CGContextAddArc(context, kuangX + 25, kuangY, kuangRadius, 0, M_PI * 2, 0);
125     CGContextFillPath(context);
126     
127     //里面的白色框
128     [[UIColor whiteColor] set];
129     CGFloat whiteRadius = kuangRadius * 0.7;
130     CGFloat whiteY = kuangY;
131     CGFloat whiteX = kuangX;
132     CGContextAddArc(context, whiteX + 25, whiteY, whiteRadius, 0, M_PI * 2, 0);
133     CGContextFillPath(context);
134     
135     //眼睛
136     [[UIColor blackColor]set];
137     CGFloat blackRadius = whiteRadius * 0.5;
138     CGFloat blackX = whiteX;
139     CGFloat blackY = whiteY;
140     CGContextAddArc(context, blackX + 25, blackY, blackRadius, 0, M_PI * 2, 0);
141     CGContextFillPath(context);
142     
143 }
144 
145 
146 @end

运行效果:

Quartz2D--iOS下的图形绘制