首页 > 技术文章 > UI绘图 - Quartz 2D 01:简介 | 简单使用

self-epoch 2021-07-09 18:27 原文

Quartz2D

1 - 绘图需要两个库:一个是 Quartz2D,它属 Core Graphics 框架;另一个库就是 OpenGL ES,是跨平台图形库 OpenGL 的一个子集。Quartz2D 是在图形上下文中进行的,每个视图都有关联的上下文,一个上下文表示一个绘制目标,上下文定义了基本的绘制属性,比如颜色、建材区域、线条宽度、样式信息、字体信息、混合模式等等

2 - 获取上下文的常见方式:(1)Quartz 提供的函数(2)Mac OS X 框架(3)iOS 的 UIKit 框架提供的函数

3 - Quartz2D 提供了许多函数,大大简化了复杂形状的创建,比如绘制多边形、椭圆等等直接调用函数即可。它提供了各种线条、形状以及图像绘制函数,仅仅限于绘制二维图形

4 - Quartz2D 的 API 是纯 C语⾔编写,数据类型和函数基本都以 CG 作为前缀,比如 CGContextRef、CGPathRef、CGContextStrokePath

5 - iOS 中⼤部分控件的内容都是通过 Quartz2D 画出来的。有些 UI 界面极其复杂且⽐较个性化,普通的 UI 控件无法实现,这时就可以利用 Quartz2D 技术实现,Quartz2D 能完成的工作有

① 绘制图形 : 线条、三角形、矩形、圆、弧等

② 绘制文字

③ 绘制、生成图片

④ 读取、生成 PDF

⑤ 截图、裁剪图片

⑥ 自定义 UI 控件

6 - 图形上下文的作用:(1)保存绘图信息、绘图状态(2)决定绘制的输出目标(输出目标可以是 PDF 文件、Bitmap 等)

注:相同的⼀套绘图序列,指定不同的 Graphics Context,就可将相同的图像绘制到不同的目标上

Bitmap 就是图片,相当于系统的 UIimage,一个 UIImage 就是一个 Bitmap

只要上下文不同,绘制的地方就不同

7 - 代码示例

① 根据坐标点绘制线条

 1 #import "QuartsView.h"
 2 
 3 @implementation QuartsView
 4 // 为什么要实现 drawRect: ⽅法才能绘图到 view 上 ?
 5 // 因为在此⽅法中才能取得跟 view 相关联的图形上下文
 6 // View 内部有个 layer 属性,drawRect:方法中取得的是一个 Layer Graphics Context
 7 // 因此绘制的东西其实是绘制在了 view 的 Layer 上
 8 
 9 // drawRect: ⽅法在什么时候被调用 ?
10 // 当 view 第一次显示到屏幕上时或调用 view 的 setNeedsDisplay、setNeedsDisplayInRect: 方法时
11 
12 // 绘制线条
13 - (void)drawRect:(CGRect)rect{
14 
15     // 第一条直线
16     // 取得和当前视图相关联的图形上下文
17     CGContextRef  ctx = UIGraphicsGetCurrentContext();
18     
19     // 状态
20     CGContextSetLineWidth(ctx, 15);// 线条宽度
21     CGContextSetLineCap(ctx, kCGLineCapRound);  // 线条起点和终点的样式为圆角
22     CGContextSetLineJoin(ctx, kCGLineJoinRound);// 线条转角的样式为圆角
23     
24     // 绘制
25     CGContextMoveToPoint(ctx, 22, 100);    // 起点
26     CGContextAddLineToPoint(ctx, 200, 300);// 终点
27     CGContextSetRGBStrokeColor(ctx, 0, 0.4, 0, 1.0);// 线条颜色
28     CGContextStrokePath(ctx); // 开始渲染
29     //CGContextFillPath(ctx); // 线条不能渲染成实心
30 
31     // 第二条直线
32     CGContextMoveToPoint(ctx, 180, 340);
33     CGContextAddLineToPoint(ctx, 300, 60);
34     CGContextSetRGBStrokeColor(ctx, 0.3, 0.2, 0.3, 1.0);
35     CGContextSetLineWidth(ctx, 10);
36     CGContextSetLineCap(ctx, kCGLineCapButt);
37     CGContextStrokePath(ctx);
38 
39 }
40 
41 @end

运行效果

② 绘制三角形、圆、椭圆、扇形、矩形、文字

  1 #import "QuartsView.h"
  2 @implementation QuartsView
  3 
  4 - (void)drawRect:(CGRect)rect{
  5 
  6     [self makeRriangle];
  7     [self makeRectangle];
  8     [self makeRound];
  9     [self makeEllipse];
 10     [self makeArc];
 11     [self makeString];
 12 
 13 }
 14 
 15 // 绘制三角形:CGContextClosePath()
 16 -(void)makeRriangle{
 17 
 18     CGContextRef ctx=UIGraphicsGetCurrentContext();
 19     // 起点
 20     CGContextMoveToPoint(ctx, 10, 40);
 21     // 第二个点
 22     CGContextAddLineToPoint(ctx, 50, 200);
 23     // 第三个点
 24     CGContextAddLineToPoint(ctx, 200, 200);
 25     // 关闭起点和终点
 26     CGContextClosePath(ctx);
 27     // 渲染图形到 layer 上
 28     CGContextStrokePath(ctx);
 29 }
 30 
 31 // 绘制矩形:直接调用给定的函数
 32 -(void)makeRectangle{
 33 
 34     CGContextRef ctx = UIGraphicsGetCurrentContext();
 35     CGContextAddRect(ctx, CGRectMake(10, 220, 150, 100));
 36     CGContextSetRGBStrokeColor(ctx, 1.0, 1.0, 0.5, 1.0);// 黄色
 37     CGContextSetLineWidth(ctx, 10);
 38     
 39     // 颜色
 40     CGContextSetRGBFillColor(ctx, 1.0, 0.6, 0, 1.0); // CGContextFillPath 下填充颜色有效且覆盖线条颜色
 41 
 42 //    // 调用 OC 的方法设置绘图的颜色
 43 //    [[UIColor purpleColor] setFill];   // 填充颜色
 44 //    [[UIColor yellowColor] setStroke]; // 线条颜色
 45 //    [[UIColor greenColor] set];// 同时设置实心和空心
 46 
 47 //    // 绘制空心矩形
 48 //    CGContextStrokePath(ctx);
 49 
 50     // 绘制实心矩形
 51     CGContextFillPath(ctx);
 52 
 53 }
 54 
 55 // 圆:注意观察圆(黄色、线宽 10)
 56 -(void)makeRound{
 57 
 58     CGContextRef ctx = UIGraphicsGetCurrentContext();
 59     // 圆心 200,100   半径 50
 60     // startAngle 开始弧度:0
 61     // endAngle   结束弧度:2*M_PI
 62     // clockwise  画圆弧方向 (0 顺时针  1 逆时针)
 63     CGContextAddArc(ctx, 200, 100, 50, 0, 2 * M_PI, 0);
 64     CGContextStrokePath(ctx);
 65 }
 66 
 67 // 圆弧:扇形
 68 -(void)makeArc{
 69 
 70 
 71     CGContextRef ctx = UIGraphicsGetCurrentContext();
 72     CGContextSetLineWidth(ctx, 5);
 73 
 74     // 扇形
 75     CGContextMoveToPoint(ctx, 340, 100);
 76     CGContextAddLineToPoint(ctx, 340, 100);
 77     CGContextAddArc(ctx, 340, 100, 50, M_PI_2, M_PI, 0);
 78 
 79     [[UIColor brownColor] set];
 80     CGContextClosePath(ctx);
 81     CGContextStrokePath(ctx);
 82 }
 83 
 84 // 椭圆
 85 -(void)makeEllipse{
 86 
 87     CGContextRef ctx = UIGraphicsGetCurrentContext();
 88     CGContextAddEllipseInRect(ctx, CGRectMake(30, 380, 220, 130));
 89     [[UIColor greenColor] set];
 90     CGContextFillPath(ctx);
 91 
 92 }
 93 
 94 // 文字
 95 -(void)makeString{
 96 
 97     NSString *str = @"挫其锐解其纷和其光同其尘";
 98     CGContextRef ctx = UIGraphicsGetCurrentContext();
 99     CGContextAddRect(ctx, CGRectMake(120, 580, 100, 80));
100     CGContextStrokePath(ctx);
101     NSMutableDictionary *md = [NSMutableDictionary dictionary];
102     md[NSForegroundColorAttributeName] = [UIColor whiteColor];
103     md[NSBackgroundColorAttributeName] = [UIColor blackColor];
104     md[NSFontAttributeName] = [UIFont systemFontOfSize:15];
105    
106     // 指定点开始绘制
107     [str drawAtPoint:CGPointMake(90, 530) withAttributes:md];
108     // 将文字绘制到指定的范围内:如果一行装不下会自动换行, 当文字超出范围后就不再显示
109     [str drawInRect:CGRectMake(120, 580, 100, 80) withAttributes:md];
110 
111 }
112 
113 @end

运行效果

③ 图片

 1 - (void)drawRect:(CGRect)rect{
 2 
 3     UIImage *image = [UIImage imageNamed:@"狗子.jpeg"];
 4     // 平铺原有图片的方式
 5     [image drawAsPatternInRect:CGRectMake(0, 24, 320, 200)];
 6     // 拉伸原有图片的方式
 7     [image drawInRect:CGRectMake(0, 230, 280, 330)];
 8     // 将原图片绘制到指定的位置
 9     [image drawAtPoint:CGPointMake(250, 400)];
10 
11 }

运行效果

素材链接

https://pan.baidu.com/s/12W8sN9J2y6pPmoLgNQdNiA

akji

推荐阅读