iOS——Quartz2D(二维图形绘制)

###一、Quartz2D 基本概述git

  • Core Graphics Framework是一套基于C的API框架,使用了Quartz做为绘图引擎。它提供了低级别、轻量级、高保真度的2D渲染。github

  • Quartz 2D是一个二维图形绘制引擎,适用于iOS和Mac OS X环境,Quartz 2D API能够不少绘制功能,如基本路径的绘制、透明度、描影、绘制阴影、透明层、颜色管理、反锯齿、PDF文档生成。框架

  • 绘图上下文Graphics Context是一个数据类型(CGContextRef),用于封装Quartz绘制图像到输出设备的信息。 Quartz中全部的对象都是绘制到一个Graphics Context中。用Quartz绘图时,能够简单地给Quartz绘图序列指定不一样的Graphics Context,就可将相同的图像绘制到不一样的设备上。咱们不须要任何设备相关的计算,这些都由Quartz替咱们完成。函数

  • Graphics Context定义了基本的绘制属性,如颜色、裁减区域、线条宽度和样式信息、字体信息、混合模式等。字体

###二、绘图方法 在iOS应用程序中,若是要使用 Core Graphics 在屏幕上进行绘制图像须要在以下方法中进行。代理

  • drawRect:方法 须要建立一个UIView对象,并实现它的drawRect:方法。视图的drawRect:方法在视图显示在屏幕上及它的内容须要更新时被调用,或者使用**setNeedsDisplay**手动调用。
// 1. 将自定义视图添加到视图上显示
- (void)viewDidLoad {
    [super viewDidLoad];
    
    DrawView *drawView = [[DrawView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:drawView];
}
// 2. 在自定义的DrawView 中绘图,当视图显示时就会调用下面的代码。
- (void)drawRect:(CGRect)rect
{

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextAddRect(ctx, CGRectMake(10, 20, 100, 100));
    CGContextSetFillColorWithColor(ctx, [UIColor grayColor].CGColor);
    CGContextDrawPath(ctx, kCGPathFill);
}
  • drawLayer: inContext:方法 这是CALayer的代理方法,须要设置图层的代理对象并使用**setNeedsDisplay**方法才能触发这个方法。
// 1.建立一个layer并设置代理为当前控制器
- (void)viewDidLoad {
    [super viewDidLoad]; 
    
    CALayer *dLayer = [CALayer layer];
    dLayer.frame = self.view.bounds;
    dLayer.delegate = self;
    [self.view.layer addSublayer:dLayer];  
    [dLayer setNeedsDisplay]; // 调用这个方法才能触发代理方法绘图
}
// 2. 在代理方法中绘图
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{

	// 绘制三角形
    CGContextSetLineWidth(ctx, 2);
    CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
    CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
    CGContextMoveToPoint(ctx, 0, 400);
    CGContextAddLineToPoint(ctx, 320, 400);
    CGContextAddLineToPoint(ctx, 160, 560);
    CGContextAddLineToPoint(ctx, 0, 400);
    CGContextFillPath(ctx);  // 填充
    CGContextStrokePath(ctx); // 描边
}

###三、Core Graphics上下文函数code

  • 绘图上下文相关函数对象

    UIGraphicsGetCurrentContext(): 获取当前绘图上下文,绘图前的第一步,由于全部的绘图都是在上下文完成的,能够理解为获取当前绘图的“画布”。图片

    CGContextSaveGState(): 保存上下文状态,这个函数的做用是将当前图形状态推入堆栈。以后,您对图形状态所作的修改会影响随后的描画操做,但不影响存储在堆栈中的拷贝。ip

    CGContextRestoreGState(): 恢复上下文状态,经过这个函数把堆栈顶部的状态弹出,返回到以前的图形状态。和CGContextSaveGState()配对使用。

    CGContextSaveGState()和CGContextRestoreGState()使用举例:整个绘图都是红色,可是中间须要有个图是灰色,这种场景就能够使用这两个函数处理了。

    // 先设置图形的填充颜色为红色
    	CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
    	// 将以前设置的状态入栈保存
    	CGContextSaveGState(ctx); 
    	CGContextAddRect(ctx, CGRectMake(10, 20, 100, 100));
    	// 设置中间图形的填充色修改成灰色
    	CGContextSetFillColorWithColor(ctx, [UIColor grayColor].CGColor);
    	CGContextDrawPath(ctx, kCGPathFillStroke);
    	// 恢复到保存前的绘图状态,那么后面的绘图就不是灰色了,而是原来的红色。
    	CGContextRestoreGState(ctx);
  • 绘图路径相关函数

    CGContextMoveToPoint(): 定位到某个点

    CGContextAddLineToPoint(): 画线,添加一条直线到一个点

    CGContextAddRect(): 画矩形

    CGContextAddEllipseInRect(): 内切圆或者椭圆

    CGContextAddQuadCurveToPoint(): 一个控制点的贝塞尔曲线

    CGContextAddCurveToPoint(): 两个控制点的贝塞尔曲线

    CGContextAddArc(): 画曲线

    CGContextSetLineDash(): 画虚线

    CGContextAddPath(): 画指定的路劲

    CGContextClosePath(): 闭合当前路径

  • 绘图设置相关函数

    CGContextSetLineWidth(): 设置线条的宽度

    CGContextSetStrokeColorWithColor(): 设置线条的颜色(使用UIColor颜色)

    CGContextSetStrokeColor(): 设置线条颜色(三色值和透明度)

    CGContextSetRGBStrokeColor(): 设置线条颜色(RGB值)

    CGContextSetFillColor(): 设置图形填充颜色(三色值和透明度)

    CGContextSetFillColorWithColor(): 设置填充颜色(UIColor值)

    CGContextSetRGBFillColor():设置填充颜色(RGB值)

    CGContextSetAlaha(): 设置透明度

    CGContextSetShouldAntialias(): 是否开启抗锯齿

    CGContextSetLineCap(): 设置直线端点的样式()

    CGContextSetLineJoin(): 设置直线链接点的样式

    CGContextSetShadow(): 设置阴影(尺寸和模糊度)

    CGContextSetShadowWithColor(): 设置阴影和阴影颜色

  • 图形填充相关函数

    CGContextFillRect(): 填充一个矩形

    CGContextStrokePath(): 描边

    CGContextFillPath(): 只填充不描边

    CGContextEOFillPath(): 使用奇偶规则填充

    CGContextDrawPath(): 绘制路径(能够选择填充的样式)

###四、使用Core Graphics绘图

  • 第一步:获取当前绘图上下文,至关于建立“画布”
CGContextRef ctx = UIGraphicsGetCurrentContext();
  • 第二步:设置要绘制的图形
//直线
    CGContextMoveToPoint(ctx, 100, 250);
    CGContextAddLineToPoint(ctx, 150, 150);
// 矩形
    CGContextAddRect(ctx, CGRectMake(10, 20, 100, 100));
// 内切圆\椭圆
    CGContextAddEllipseInRect(ctx, CGRectMake(120, 20, 100, 100));
// 三角形
    CGContextMoveToPoint(ctx, 0, 400);
    CGContextAddLineToPoint(ctx, 320, 400);
    CGContextAddLineToPoint(ctx, 160, 560);
    CGContextClosePath(ctx);
// 一个控制点的贝塞尔曲线
    CGContextAddQuadCurveToPoint(ctx, 80, 100, 160, 300);
// 两个控制点的贝塞尔曲线
    CGContextAddCurveToPoint(ctx, 80, 100, 240, 500, 320, 300);
// 弧线
    CGContextAddArc(ctx, 240, 200, 80, 0, M_PI_2, NO);
// 绘制图片
    CGRect imageFrame = CGRectMake(10, 30, 300, 300);
    // 获取图片数据
    NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"png"]; 
    UIImage *img = [UIImage imageWithContentsOfFile:imagePath];
    
    // 设置上下文当前转换矩阵(CTM),不然图片倒置
    CGContextTranslateCTM(context, 0, imageFrame.size.height);
    CGContextScaleCTM(context, 1, -1);
    CGContextDrawImage(context, imageFrame, img.CGImage); // 绘制
    // 或者以下绘制,不须要设置CTM
    [img drawInRect:imageFrame];
  • 第三步:设置图形的属性(颜色、线条……)
CGContextSetLineWidth(ctx, 5); // 线宽
    CGContextSetFillColorWithColor(ctx, [UIColor blueColor].CGColor); // 填充颜色
    CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor); // 线条颜色
    CGContextSetShouldAntialias(ctx, YES); // 抗锯齿
    CGContextSetLineCap(ctx, kCGLineCapRound); // 线头颜色
    CGContextSetLineJoin(ctx, kCGLineJoinBevel); // 连接点样式
  • 第四步:绘图(填充)
CGContextFillPath(ctx);    // 填充
    CGContextStrokePath(ctx); // 描边
    // 或者填充并描边 
    CGContextDrawPath(ctx, kCGPathFillStroke);

###五、使用UIBezierPath绘图 UIKit中的UIBezierPath是Core Graphics框架关于path的一个封装(封装为OC的方法)。 使用UIBezierPath绘图不须要手动获取绘图上下文,当drawRect方法被调用时,UIView的绘图上下文属于当前图形上下文。

  • 实例化一个path对象
// 不设置图形路径
    UIBezierPath *path = [UIBezierPath bezierPath];
// 矩形路径
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 100, 200, 200)];
// 内切圆\椭圆路径
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 100, 200, 200)];
//圆角矩形路径 
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 100, 200, 200) cornerRadius:20];
// 弧线路径,ArcCenter:原点、radius:半径、startAngle:起点弧度、endAngle:终端弧度、clockwise:是否顺时针
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:50 startAngle:0 endAngle:M_PI_2 clockwise:YES];
  • 添加路径
// 移动到某个点
    [path moveToPoint:p1];
	
    // 添加一条线到某个点
    [path addLineToPoint:p2];
	
    // 添加一条贝塞尔曲线
    [path addQuadCurveToPoint:p1 controlPoint:p2];
	
    // 添加一条弧线
    [path addArcWithCenter:p1 radius:50 startAngle:M_PI_4 endAngle:M_PI_2 clockwise:YES];
	
    // 闭合路径
    [path closePath];	
	
    // 移除全部的点
    [path removeAllPoints];
  • 设置路径属性
// 设置填充颜色
    [[UIColor redColor] setFill]; 
	
    // 设置描边颜色
   [[UIColor whiteColor] setStroke]; 
   	
   // 线宽
    path.lineWidth = 5; 
    
    // 线头样式
    path.lineCapStyle = kCGLineCapRound;
    
    // 线链接点样式
    path.lineJoinStyle = kCGLineJoinMiter;
    
    // 链接点的斜距(角的内点和外点的距离),链接样式得为kCGLineJoinMiter
    path.miterLimit = 20;
  • 绘图(填充)
[path fill];    // 填充
    [path stroke];  // 描边

###六、实例Demo下载

下载连接:https://github.com/fuqinglin/Quartz2DDemos.git

相关文章
相关标签/搜索