Quartz 2D

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Quartz 2D相关的知识,希望对你有一定的参考价值。

1.什么是Quart 2D呢?

不知道,但是可以通过Quart2D绘制图形,自定义控件等等.

2.如何通过Quart 2D绘制图形和自定义控件?

有两种方式:C语言/OC;OC其实最后还是转换成C,那么用C会不会效率稍高?

3.基本图形的绘制

  • C语言方式
    • 获取当前图形上下文 :
          CGContextRef ctx = UIGraphicsGetCurrentContext();
    • 绘制图形:
      圆:CGContextRef _Nullable c:图形上下文; CGFloat x, CGFloat y:圆心坐标;CGFloat radius:半径;CGFloat startAngle:开始角度;CGFloat endAngle:结束角度;int clockwise:绘制的方向(顺时针还是逆时针)
      [CGContextAddArc(CGContextRef _Nullable c, CGFloat x, CGFloat y, CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise) ];
      椭圆:CGRect rect:一个矩形范围.
      [CGContextAddEllipseInRect(CGContextRef _Nullable c, CGRect rect) ];
      线:(给定一些点,连接成线) const CGPoint * _Nullable points:CGPoint类型的数组;size_t count:有几个点
      [CGContextAddLines(CGContextRef _Nullable c,
      const CGPoint * _Nullable points, size_t count) ];
      矩形:
      [CGContextAddRect(CGContextRef _Nullable c, CGRect rect) ];

      线:
      [CGContextMoveToPoint(CGContextRef  _Nullable c, CGFloat x, CGFloat y) ];
      [CGContextAddLineToPoint(CGContextRef  _Nullable c, CGFloat x, CGFloat y) ];
    • 渲染:填充/描边
    •   [CGContextStrokePath(CGContextRef  _Nullable c) ];//描边
      [CGContextFillPath(CGContextRef _Nullable c) ];//填充
  • OC方式
    • 绘制
    • 圆:  
      [UIBezierPath bezierPathWithArcCenter:(CGPoint) radius:(CGFloat) startAngle:(CGFloat) endAngle:(CGFloat) clockwise:(BOOL)];
      矩形:
      [UIBezierPath bezierPathWithRect:(CGRect)];

      圆角矩形:cornerRadius:(CGFloat):圆角实际上通过在矩形边角处绘制圆,然后将弧线外面部分截取掉实现的.此参数代表圆的半径,值越大,边角越圆 [UIBezierPath bezierPathWithRoundedRect:(CGRect) cornerRadius:(CGFloat)];

      线:
        UIBezierPath *path = [UIBezierPath bezierPath];//首先要获取UIBezierPath对象,调用对象方法画线
         [path moveToPoint:(CGPoint)];
         [path addLineToPoint:(CGPoint)];
    • 渲染
    •    UIBezierPath *path = [UIBezierPath bezierPath];
         [path fill];
         [path stroke];

 4.奇偶性原则

   有图形A,图形B,图形A,B有部分内容重合,设置使用奇偶性原则,设置填充模式,则重合次数为奇数次填充,偶数次不填充.

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextAddArc(ctx, 100, 100, 100, 0, M_PI * 2, 0);
    CGContextAddArc(ctx, 200, 100, 100, 0, M_PI * 2, 0);
    CGContextDrawPath(ctx, kCGPathEOFill);

技术分享

增加一行代码,再多画一个圆:

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextAddArc(ctx, 100, 100, 100, 0, M_PI * 2, 0);
    CGContextAddArc(ctx, 200, 100, 100, 0, M_PI * 2, 0);
    CGContextAddArc(ctx, 150, 200, 100, 0, M_PI * 2, 0);
    CGContextDrawPath(ctx, kCGPathEOFill);

效果:

技术分享

多出来的三角形:实际上多出来的三角形刚好是三个圆的起点.此种方式默认将图形的路径连接起来了.三角形部分同样遵守奇偶性原则.

OC实现同样的效果:

   UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:1];
    [path addArcWithCenter:CGPointMake(200, 100) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:1];
    [path addArcWithCenter:CGPointMake(150, 200) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:1];
    path.usesEvenOddFillRule = YES;

    [path fill];

那么如何才能设置奇偶性,同时又不让各个图形的路径连接起来呢?

OC实现:

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:1];
    UIBezierPath *path2 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 100) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:1];
    [path appendPath:path2];
    UIBezierPath *path3 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 200) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:1];
    [path appendPath:path3];
    path.usesEvenOddFillRule = YES;
    [path fill];

技术分享

C实现方式:

    CGContextRef ctx = UIGraphicsGetCurrentContext();
CGMutablePathRef path
= CGPathCreateMutable(); CGPathAddArc(path, NULL, 100, 100, 100, 0, M_PI * 2, 1);
CGMutablePathRef path2
= CGPathCreateMutable(); CGPathAddArc(path2, NULL, 200, 100, 100, 0, M_PI * 2, 1);
CGMutablePathRef path3
= CGPathCreateMutable(); CGPathAddArc(path3, NULL, 150, 200, 100, 0, M_PI * 2, 1);
CGPathAddPath(path, NULL, path2); CGPathAddPath(path, NULL, path3); CGContextAddPath(ctx, path); CGContextDrawPath(ctx, kCGPathEOFill);

除了这些应该还有很多其他的实现方式.另外,我还是不理解直接直接绘制的方式和通过路径绘制的方有什么区别.

5.非零环绕数规则.

效果:

技术分享C实现方式:

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddArc(path, NULL, 200, 200, 50, 0, M_PI * 2, 1);

    CGMutablePathRef path2 = CGPathCreateMutable();
    CGPathAddArc(path2, NULL, 200, 200, 100, 0, M_PI * 2, 0);

    CGMutablePathRef path3 = CGPathCreateMutable();
    CGPathAddArc(path3, NULL, 200, 200, 200, 0, M_PI * 2, 1);

    CGPathAddPath(path, NULL, path2);
    CGPathAddPath(path, NULL, path3);

    CGContextAddPath(ctx, path);
    CGContextDrawPath(ctx, kCGPathFill);

貌似纯OC代码不能实现,因为如果最后通过函数 CGContextDrawPath(ctx, kCGPathFill);渲染,就必须获取当前图形上下文.而如果不同过该函数渲染,纯OC貌似只有Fill,Stroke两种渲染方式.

  CGContextRef ctx = UIGraphicsGetCurrentContext();

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 200) radius:50 startAngle:0 endAngle:M_PI * 2 clockwise:1];
    UIBezierPath *path2 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 200) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:0];
    UIBezierPath *path3 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(200, 200) radius:200 startAngle:0 endAngle:M_PI * 2 clockwise:1];

    CGContextAddPath(ctx, path.CGPath);
    CGContextAddPath(ctx, path2.CGPath);
    CGContextAddPath(ctx, path3.CGPath);

    CGContextDrawPath(ctx, kCGPathFill);

 

  

 

以上是关于Quartz 2D的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发UI篇—Quartz2D使用(截屏)

使用 Quartz 2D 解析 pdf 时获取文本位置

如何在 Core Graphics / Quartz 2D 中绘制圆角矩形?

iOS开发中 Quartz2D使用详细 简介

IOS Quartz2D 通过UIColor生成图片

iOS开发UI篇—Quartz2D使用(截屏)