Quartz 2D绘图

#Quartz 2D绘图 ##Quartz 2D 概述git

  • 概述:
    Quartz 2D是一个⼆维图形绘制引擎,支持iOS环境和Mac OS X环境。咱们可使⽤用 Quartz 2D API来实现许多功能,如基本路径的绘制、透明度、描影、绘制阴影、透明层、 颜⾊色管理、反锯齿、PDF⽂文档⽣生成和PDF元数据访问。在须要的时候,Quartz 2D还能够借 助图形硬件的功能。Quartz 2D 的API是Core Graphics框架的一部分,所以其中的不少 数据类型和⽅方法都是以CG开头的。会常常⻅见到Quartz 2D(Quartz)和Core Graphics 两个术语交互使⽤用。

##Graphics Contextgithub

  • 概述:
    Core Graphics API全部的操做都在一个上下⽂文中进⾏行。因此在绘图以前须要获取该 上下⽂文并传⼊入执⾏行渲染的函数中。若是你正在渲染一副在内存中的图⽚片,此时就须要传⼊入 图⽚片所属的上下⽂文。得到一个图形上下⽂文是咱们完成绘图任务的第一步,你能够将图形上 下⽂文理解为⼀块画布。若是你没有获得这块画布,那么你就⽆没法完成任何绘图操做。
  • Page
    Quartz 2D在图像中使⽤用了绘画者模型(painter’s model)。在绘画者模型中,每一个连续的绘制操做都是将 ⼀个绘制层(a layer of ‘paint’)放置于一个画布 (‘canvas’),咱们一般称这个画布为Page。 Page上的绘 图能够经过额外的绘制操做来叠加更多的绘图。Page上 的图形对象只能经过叠加更多的绘图来改变。这个模型 容许咱们使⽤用⼩小的图元来构建复杂的图形。 Page能够是一张纸(若是输出设备是打印机),也能够是 虚拟的纸张(若是输出设备是PDF⽂文件),还能够是bitmap 图像。这根据实际使⽤用的graphics context⽽而定。

'画布' “page”canvas

// 1. 将自定义视图添加到视图上显示
- (void)viewDidLoad {
    [super viewDidLoad];
    
    CoreGraphicsView *cgView = [[CoreGraphicsView alloc] initWithFrame:self.view.bounds];
    cgView.backgroundColor = [UIColor blackColor];
    
    [self.view addSubview:cgView];
    
    // 2. 在自定义的DrawView 中绘图,当视图显示时就会调用下面的代码。
- (void)drawRect:(CGRect)rect
{

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextAddRect(ctx, CGRectMake(10, 20, 100, 100));
    CGContextSetFillColorWithColor(ctx, [UIColor grayColor].CGColor);
    CGContextDrawPath(ctx, kCGPathFill);
}
}
  • Quartz提供了如下⼏几种类型的Graphics Context
    1.Bitmap Graphics Context
    2.PDF Graphics Context 3.Window Graphics Context
    4.Layer Graphics Context
    5.Printer Graphics Context

###Graphics Context 读解c#

  • 一个Graphics Context表示⼀个绘制目标。它包含绘制系统⽤用于完成绘制指令的绘制参 数和设备相关信息
  • Graphics Context定义了基本的绘制属性,如颜色、裁减区域、线条宽度和样式信息、 字体信息、混合模式等
  • 在iOS应⽤用程序中,若是要在屏幕上进⾏行绘制,须要建立一个UIView对象,并实现它的 drawRect:⽅法。视图的drawRect:方法在视图显⽰在屏幕上及它的内容须要更新时被调用
  • 在调⽤用⾃自定义的drawRect:后,视图对象⾃自动配置绘图环境以便能⽴即执行绘图操做
  • 做为配置的⼀一部分,视图对象将为当前的绘图环境建立⼀Graphics Context。经过调 ⽤用UIGraphicsGetCurrentContext()⽅法能够获取当前的Graphics Context

##Quartz 2D坐标系框架

坐标系统定义是被绘制到Page上的对象的位置及⼤小范围,如图所示。咱们在用户空间坐标系统(user-space coordination system,简称⽤户空间)中指定图形的位置及⼤小。坐标值是⽤浮点数来定义的。函数

  • Quartz中默认的坐标系统是:原点(0, 0) 在左下角。沿着X轴从左到右坐标值逐渐增大;沿着Y轴从下到上坐标值逐渐增大
  • 有一些技术在设置它们的graphicscontext时使⽤了不一样于Quartz的默认坐标系统。最多见的一种修改的坐标系统是原点位于左上角,而沿着Y轴从上到下坐标值逐渐 增大。 **例如:**UIView中的 UIGraphicsGetCurrentContext方法返回的图 形上下文就是用的是这种坐标系

输入图片说明

###UIKit坐标系:字体

  • 原点(0,0)在屏幕的左上角,X轴向右正向延伸,Y轴向下正向延伸
  • iOS的像素分辨率会随设备的硬件而变化,iPhone4第一次引入了视网膜屏幕,像素分辨率为960 * 640,恰好是前⼀代iPod和iPhone像素分辨率( 480 * 320)的两倍
  • 在绘图时,须要使用“点”的概念来思考问题,⽽不是像素。也就是说在点坐标系中绘图,不是硬件的像素坐标系
  • 虽然这些设备的像素分辨率不一样,但⽤到的坐标系保持不变(以点为单位)。在iPhone4 上,⼀个点会⽤2像素宽度来绘制

###坐标系的转换:spa

  • CGContextRotateCTM(CGContextRef c, CGFloat angle)⽅法能够相对原点旋转上下文坐标系
  • CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)方法能够相对原点平移上下文坐标系
  • CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)⽅法能够缩放上下⽂坐标系

注意:
转换坐标系前,使用CGContextSaveGState(CGContextRef c)保存当前上下文状态 坐标系转换后,使用CGContextRestoreGState(CGContextRef c)能够恢复以前保存的上下⽂状态 ##基本绘图 ###Quartz 2D绘图流程:code

  1. 获取上下⽂
  2. 保存上下⽂
  3. 建立及设置路径
  4. 将路径添加到上下文设置上下⽂状态(边框颜色,填充颜色,线条宽度,线段链接式,线段首尾样式,虚线样式等)
  5. 绘制路径
  6. 释放路径
  7. 恢复上下⽂

绘制简单图形代码对象

- (void)drawGraphics {
    
    CGContextRef cxt =  UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(cxt, [UIColor redColor].CGColor);
    CGContextSetLineWidth(cxt, 5);
    
    // 一、绘制矩形
    CGContextAddRect(cxt, CGRectMake(20, 100, 320, 150));
    CGContextDrawPath(cxt, kCGPathStroke);
    
    // 保存上下文状态(入栈)
    CGContextSaveGState(cxt);
    
    // 二、绘制内切椭圆、圆
    CGContextAddEllipseInRect(cxt, CGRectMake(20, 260, 320, 150));
    CGContextSetStrokeColorWithColor(cxt, [UIColor orangeColor].CGColor);
    CGContextSetLineWidth(cxt, 10);
    CGContextDrawPath(cxt, kCGPathStroke);
    
    // 恢复上下文状态(出栈)
    CGContextRestoreGState(cxt);
    
    
    // 三、绘制圆弧
    CGContextMoveToPoint(cxt, 250, 500);
    CGContextAddArc(cxt, 200, 500, 50, 0, M_PI_2, NO);
    
    // 四、绘制贝塞尔曲线
    // cpx、cpy: 控制点的坐标, x、y目标点的坐标
    // CGContextAddQuadCurveToPoint(cxt, <#CGFloat cpx#>, <#CGFloat cpy#>, <#CGFloat x#>, <#CGFloat y#>)
    
    // CGContextAddCurveToPoint(<#CGContextRef  _Nullable c#>, <#CGFloat cp1x#>, <#CGFloat cp1y#>, <#CGFloat cp2x#>, <#CGFloat cp2y#>, <#CGFloat x#>, <#CGFloat y#>)
    
    CGContextDrawPath(cxt, kCGPathStroke);
    
}

###路径:

  1. 路径定义了一个或多个形状,或是子路径。
  2. ⼀个⼦路径可由直线,曲线,或者同时由二者构成。
  3. 它能够是开放的,也能够是闭合的。
  4. ⼀个子路径能够是简单的形状,如线、圆、矩形、星形;
  5. 也能够是复杂的形状,如⼭脉的轮廓或者是涂鸦。
  6. 路径能够是开放的,也能够是封闭的;对于封闭路径能够空⼼的也能够是实心的 ###绘制文字
- (void)drawText {
    
    CGRect rect = CGRectMake(20, 30, 200, 20);
    [text drawInRect:rect withAttributes:@{NSForegroundColorAttributeName : [UIColor redColor],
                                           NSBackgroundColorAttributeName:[UIColor whiteColor],
                                           NSFontAttributeName : [UIFont systemFontOfSize:20]}];
}

###绘制图形的基本属性

- (void)drawLines {
    
    // 一、获取当前绘图上下文(绘图环境)、能够理解为建立一块画布
    CGContextRef cxt = UIGraphicsGetCurrentContext();
    
    // 二、移动到某个点
    CGContextMoveToPoint(cxt, 20, 100);
    
    // 三、添加一条直线到某个点
    CGContextAddLineToPoint(cxt, 300, 100);
    CGContextAddLineToPoint(cxt, 160, 300);
    
    // 闭合路径
    CGContextClosePath(cxt);

    // 四、设置描边和填充颜色
    CGContextSetStrokeColorWithColor(cxt, [UIColor redColor].CGColor);
    //CGContextSetRGBStrokeColor(cxt, 200/255.0, 300/255.0, 10/255.0, 1);
    // CGContextSetCMYKStrokeColor(cxt, 0.1, 0.3, 0.5, 0.8, 1);
    CGContextSetFillColorWithColor(cxt, [UIColor whiteColor].CGColor);

    // 五、设置线条宽度
    CGContextSetLineWidth(cxt, 5);
    
    // 六、设置线头样式
    CGContextSetLineCap(cxt, kCGLineCapRound);
    
    // 七、设置线条链接点的样式
    CGContextSetLineJoin(cxt, kCGLineJoinRound);
    
    // 八、设置虚线
    // CGFloat lengths[] = {2,10,2};
    // CGContextSetLineDash(cxt, 0, lengths, 3);
    
    // 九、是否开启抗锯齿
    CGContextSetShouldAntialias(cxt, YES);
    
    
    // 十、绘制描边
    // CGContextStrokePath(cxt);
    // 十一、绘制填充
    // CGContextFillPath(cxt);
    
    // 十二、绘制描边、填充、描边和填充、奇偶填充:kCGPathFill,kCGPathEOFill,kCGPathStroke,kCGPathFillStroke, kCGPathEOFillStroke
    CGContextDrawPath(cxt, kCGPathFillStroke);
    
}

###构建路径的函数说明:

  • CGContextBeginPath // 开始一个新路径
  • CGContextMoveToPoint // 设置路径的起点
  • CGContextClosePath // 关闭路径
  • CGContextAddPath // 添加路径
  • CGContextAddLineToPoint // 在指定点添加线
  • CGContextAddLines // 添加多条线
  • CGContextAddRect // 添加矩形
  • CGContextAddRects // 添加多个矩形
  • CGContextAddEllipseInRect // 在矩形中添加椭圆
  • CGContextAddArc // 添加弧线
  • CGContextAddArcToPoint // 在指定点添加弧线
  • CGContextAddCurveToPoint // 在指定点添加曲线

###绘制路径的函数说明:

  • CGContextDrawPath// 绘制路径
  • CGContextFillPath // 实心路径
  • CGContextFillRect // 实心矩形
  • CGContextFillRects // 多个实心矩形
  • CGContextFillEllipseInRect // 在矩形区域中绘制实⼼椭圆
  • CGContextStrokePath // 空⼼心路径
  • CGContextStrokeRect // 空⼼心矩形
  • CGContextStrokeRectWithWidth // 使⽤用宽度绘制空⼼矩形
  • CGContextStrokeEllipseInRect// 在矩形区域中绘制空⼼椭圆

###绘图状态参数说明:
CGContextSetLineWidth// 线条宽度 CGContextSetBlendMode // 设置混合模式 CGContextSetShouldAntialias // 设置抗锯齿效果 CGContextSetLineCap // 设置线条收尾点样式 CGContextSetLineJoin // 设置线条链接点样式 CGContextSetLineDash// 设置虚线

##绘图实战 Demo下载
简单的绘图

Bezier绘图Demo

绘图练习