Quartz 2D

Quartz 2D:

  • Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac OS X系统(跨平台,纯C语言)。包含在Core Graphics框架中。

Quartz 2D能完成的工作:

  • 绘制图形: 线条/三角形/矩形/圆/弧等
  • 绘制文字
  • 绘制/生成图片
  • 读取/生成PDF
  • 自定义UI控件
  • ... ...

Quartz 2D绘图主要步骤:

  • 通过Quartz 2D原生API绘图:

    • 获取[图形上下文]对象
    • 向[图形上下文]对象中添加[路劲]
    • 渲染(把[图形上下文]中的图形绘制到对应的设备上)

图形上下文CGContextRef

  • 图形上下文(Graphics Context): 是一个CGContextRef类型的数据
  • 图形上下文中主要包含如下信息:
    • 绘制路径(各种各样的图形)
    • 绘图状态(颜色、线宽、样式、旋转、缩放、平移、图片剪裁区域等)
    • 输出目标(绘制到什么地方去?UIView、PDF、打印机等)

图形上下文:

提供了以下几种图形上下文:

  • Bitmap Graphics Context --效果画到图片上
  • PDF Graphics Context --画到PDF上
  • Window Graphics Context --画到Mac电脑窗口上
  • Layer Graphics Context(UI 控件) --画到UI控件上
  • Printer Graphics Context --画到打印机

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

通过UIBezierPath + 图形上下文绘制图形:

  • 获取图形上下文对象
  • 创建UIBezierPath对象
  • 向UIBezierPath对象中绘制图形
  • 把UIBezierPath对象添加到上下文中
  • 把上下文对象渲染到设备上

PS: UIBezierPath对象可以独立使用,无需手动获取 图形上下文 对象,这里为了更好的理解 图形上下文对象,采取手动获取图形上下文对象的方式来绘图。

自定义UIView时,实现文件中:

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

即:在drawRect:方法中才能取得跟view相关联的图形上下文 我们才能绘制各种图形。

drawRect: 方法仅在view第一次显示在Window上时调用一次,如果想重新调用 需要手动调用setNeedsDisplay或setNeedsDisplayInRect:方法。

不可手动调用drawRect: 方法,该方法是由系统在需要调用的时候调用--不能主动调用该方法。

  • Quartz 2D原生API绘制:

    • 绘制直线:
//1.获取图形上下文
    CGContextRef ref = UIGraphicsGetCurrentContext();
    
    //2. 绘制各种路径
    //2.1 设置一个起点
    CGContextMoveToPoint(ref, 20, 100);
    //2.2 设置一个终点
    CGContextAddLineToPoint(ref, 100, 160);
    //3. 渲染
    CGContextStrokePath(ref);
  • 绘制三角形:
//1.获取图形上下文
    CGContextRef ref = UIGraphicsGetCurrentContext();
    
    //2. 绘制各种路径
    //2.1 设置一个起点
    CGContextMoveToPoint(ref, 20, 100);
    //2.2 设置一个终点
    CGContextAddLineToPoint(ref, 100, 160);
    //2.3 再添加一个终点
    CGContextAddLineToPoint(ref, 150, 100);
    
    //2.4 关闭路径
    CGContextClosePath(ref);
    
    //3. 渲染
    CGContextStrokePath(ref);
  • UIBezierPath绘制图形:
    • 绘制直线:
//1. 获取图形上下文
    CGContextRef ref = UIGraphicsGetCurrentContext();
    //2. 创建UIBezierPath对象
    UIBezierPath *path = [UIBezierPath bezierPath];
    //3. 向UIBezierPath添加路径
    [path moveToPoint:CGPointMake(30, 100)];
    [path addLineToPoint:CGPointMake(300, 300)];
    //4. 把UIBezierPath对象添加到上下文中
    CGContextAddPath(ref, path.CGPath);
    //设置状态信息
    //i. 线宽
    CGContextSetLineWidth(ref, 10);
    //ii. 设置线段两端样式
    /*
     typedef CF_ENUM(int32_t, CGLineCap) {
     kCGLineCapButt,        //默认
     kCGLineCapRound,
     kCGLineCapSquare
     };
     */
    CGContextSetLineCap(ref, kCGLineCapRound);
    //iii. 设置线段连接处的样式
    /*
     typedef CF_ENUM(int32_t, CGLineJoin) {
     kCGLineJoinMiter,      //默认
     kCGLineJoinRound,
     kCGLineJoinBevel
     };
     */
    CGContextSetLineJoin(ref, kCGLineJoinRound);
    //iV. 设置绘图颜色
    //    [[UIColor redColor] setStroke]; //画边的时候使用红色 --仅用于渲染时 为kCGPathStroke时
    //    [[UIColor yellowColor] setFill];    //设置填充时颜色 --kCGPathFill
    [[UIColor blueColor] set];  //填充和描边 使用同一颜色
    //5. 渲染
    //    CGContextStrokePath(ref);
    //上面所有的设置状态的代码,都会将状态应用于当前上下文中的所有路径
    //    CGContextDrawPath(ref, kCGPathStroke);    //与[[UIColor redColor] setStroke];对应
    //    CGContextDrawPath(ref, kCGPathFill);      //与[[UIColor yellowColor] setFill];对应
    CGContextDrawPath(ref, kCGPathFillStroke);  //既填充也描边    //与[[UIColor blueColor] set];对应
  • 绘制三角形:
//1. 获取上下文
    CGContextRef ref = UIGraphicsGetCurrentContext();
    //2. 创建UIBezierPath对象
    UIBezierPath *path = [UIBezierPath bezierPath];
    //3. 向UIBezierPath添加路径
    [path moveToPoint:CGPointMake(100, 200)];
    [path addLineToPoint:CGPointMake(160, 300)];
    [path addLineToPoint:CGPointMake(220, 200)];
    //关闭路径
    [path closePath];
    //4. 把UIBezierPath对象添加到上下文中
    CGContextAddPath(ref, path.CGPath); //OC对象 转 C语言
    //5. 渲染
    //    CGContextStrokePath(ref);
    //or
    /*
     typedef CF_ENUM (int32_t, CGPathDrawingMode) {
     kCGPathFill,
     kCGPathEOFill,
     kCGPathStroke,
     kCGPathFillStroke,
     kCGPathEOFillStroke
     };
     */
    CGContextDrawPath(ref, kCGPathStroke);
  • 绘制矩形:
//获取上下文
    CGContextRef ref = UIGraphicsGetCurrentContext();
    //创建UIBezierPath
    //向UIBezierPath中添加路径
    //绘制矩形
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 50, 200, 100)];
    //把UIBezierPath添加到上下文中
    CGContextAddPath(ref, path.CGPath);
    //渲染
    /*
     typedef CF_ENUM (int32_t, CGPathDrawingMode) {
     kCGPathFill,
     kCGPathEOFill,
     kCGPathStroke,
     kCGPathFillStroke,
     kCGPathEOFillStroke
     };
     */
    CGContextDrawPath(ref, kCGPathStroke);
    //    CGContextDrawPath(ref, kCGPathFill); //填充
  • 绘制椭圆:
//获取上下文
    CGContextRef ref = UIGraphicsGetCurrentContext();
    //创建UIBezierPath
    //向UIBezierPath中添加路径
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 200, 100)];
    //把UIBezierPath添加到上下文中
    CGContextAddPath(ref, path.CGPath);
    //渲染
    /*
     typedef CF_ENUM (int32_t, CGPathDrawingMode) {
     kCGPathFill,
     kCGPathEOFill,
     kCGPathStroke,
     kCGPathFillStroke,
     kCGPathEOFillStroke
     };
     */
    CGContextDrawPath(ref, kCGPathStroke);
    //    CGContextDrawPath(ref, kCGPathFill); //填充
  • 绘制圆形:

    • 第一种方式: 画椭圆方法 --宽高相等
//获取上下文
    CGContextRef ref = UIGraphicsGetCurrentContext();
    //创建UIBezierPath
    //向UIBezierPath中添加路径
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 100, 100)];
    //把UIBezierPath添加到上下文中
    CGContextAddPath(ref, path.CGPath);
    //渲染
    /*
     typedef CF_ENUM (int32_t, CGPathDrawingMode) {
     kCGPathFill,
     kCGPathEOFill,
     kCGPathStroke,
     kCGPathFillStroke,
     kCGPathEOFillStroke
     };
     */
    CGContextDrawPath(ref, kCGPathStroke);
    //    CGContextDrawPath(ref, kCGPathFill); //填充
- 第二种方式: 绘制矩形 --宽高相等 cornerRadius: 边长/2.0
//获取上下文
    CGContextRef ref = UIGraphicsGetCurrentContext();
    //创建UIBezierPath
    //向UIBezierPath中添加路径
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 100, 100) cornerRadius:50];
    //把UIBezierPath添加到上下文中
    CGContextAddPath(ref, path.CGPath);
    //渲染
    /*
     typedef CF_ENUM (int32_t, CGPathDrawingMode) {
     kCGPathFill,
     kCGPathEOFill,
     kCGPathStroke,
     kCGPathFillStroke,
     kCGPathEOFillStroke
     };
     */
    CGContextDrawPath(ref, kCGPathStroke);
    //    CGContextDrawPath(ref, kCGPathFill); //填充
- 第三种方式: 绘制圆弧方式画一个圆
//获取上下文
    CGContextRef ref = UIGraphicsGetCurrentContext();
    //创建UIBezierPath
    //向UIBezierPath中添加路径
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 200) radius:50 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
    //把UIBezierPath添加到上下文中
    CGContextAddPath(ref, path.CGPath);
    //渲染
    /*
     typedef CF_ENUM (int32_t, CGPathDrawingMode) {
     kCGPathFill,
     kCGPathEOFill,
     kCGPathStroke,
     kCGPathFillStroke,
     kCGPathEOFillStroke
     };
     */
    CGContextDrawPath(ref, kCGPathStroke);
    //    CGContextDrawPath(ref, kCGPathFill); //填充
  • 绘制圆弧:
//获取上下文
    CGContextRef ref = UIGraphicsGetCurrentContext();
    //创建UIBezierPath
    //向UIBezierPath中添加路径
    //画弧
    //ArcCenter: 圆心
    //radius: 半径
    //startAngle: 开始弧度  --1弧度 = 180度
    //endAngle: 结束弧度
    //绘制一个弧 clockwise: 顺时针或逆时针
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 200) radius:50 startAngle:0 endAngle:M_PI_2 clockwise:NO];
    //把UIBezierPath添加到上下文中
    CGContextAddPath(ref, path.CGPath);
    //渲染
    /*
     typedef CF_ENUM (int32_t, CGPathDrawingMode) {
     kCGPathFill,
     kCGPathEOFill,
     kCGPathStroke,
     kCGPathFillStroke,
     kCGPathEOFillStroke
     };
     */
    CGContextDrawPath(ref, kCGPathStroke);
    //    CGContextDrawPath(ref, kCGPathFill); //填充
  • 绘制圆环:
//获取上下文
    CGContextRef ref = UIGraphicsGetCurrentContext();
    //创建UIBezierPath
    //向UIBezierPath中添加路径
    //画圆环
    //直接画一个圆 设置线宽 --推荐使用这种方式
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 200) radius:50 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
    CGContextSetLineWidth(ref, 20);   //线宽 里外各一半
    //把UIBezierPath添加到上下文中
    CGContextAddPath(ref, path.CGPath);
    //渲染
    /*
     typedef CF_ENUM (int32_t, CGPathDrawingMode) {
     kCGPathFill,
     kCGPathEOFill,
     kCGPathStroke,
     kCGPathFillStroke,
     kCGPathEOFillStroke
     };
     */
    CGContextDrawPath(ref, kCGPathStroke);
    //    CGContextDrawPath(ref, kCGPathFill); //填充

参考资料:
传智播客教程
iOS-Quartz2D

代码

你可能感兴趣的:(Quartz 2D)