CGContextRef&CGMutablePathRef&UIBezierPath简单学习
阅读原文时间:2023年07月14日阅读:1

简单的四句介绍

Quartz是一个二维绘图引擎,使用的是CoreGraphics库,同时支持iOS和Mac系统

CGContextRef:获取图形上下文.或者叫作用域,即画布,他是专门用来保存绘画期间的各种数据的

UIBezierPath是对CGPathRef的封装。创建矢量图形时,拆解成一条或者多条线段,拼接起来,每条下端的终点都是下一条线段的起点

当我们绘制路径时,Path的信息就会被Graphics context重置。 如果我们想要保存path信息,并多次使用它,我们就可以用到CGPathCreatMutable申请路径,然后用CGPathAddLintToPoint等方法来添加路径。

一起学习,共同进步,可下载对应Demo

1.设置点和线

介绍属性

  • 先设置一个起点
  • 添加一个中间点
  • 画一个矩形
  • 画一个圆形
  • 画一个扇形
  • 二阶曲线
  • 三阶曲线

CGContextRef

UIBezierPath

CGMutablePathRef

CGContextMoveToPoint

moveToPoint

CGPathMoveToPoint

CGContextAddLineToPoint

addLineToPoint

CGPathAddRect

CGContextAddRect

bezierPathWithRect

CGPathAddRect

CGContextAddEllipseInRect

bezierPathWithOvalInRect

CGPathAddEllipseInRect

CGContextAddArc

addArcWithCenter

CGPathAddArcToPoint

CGContextAddQuadCurveToPoint

addQuadCurveToPoint

CGPathAddQuadCurveToPoint

CGContextAddCurveToPoint

addCurveToPoint

CGPathAddCurveToPoint

2、设置线的属性

这些设置线属性的API都是通用的

  • 线宽 CGContextSetLineWidth
  • 线的颜色 CGContextSetStrokeColorWithColor
  • 填充颜色 CGContextSetFillColorWithColor
  • line join CGContextSetLineCap
  • line cap CGContextSetLineJoin
  • 透明度 CGContextSetAlpha
  • 设置阴影 CGContextSetShadow
  • 设置阴影颜色 CGContextSetShadowWithColor
  • 切割操作 CGContextClip

思维导图

        

CGContextRef介绍

Quartz2d是一个二维绘图引擎,使用的是CoreGraphics库,同时支持iOS和Mac系统

有点难,比较底层,操作系统层api一般都是纯C开发的,有针对性的开发才会用到

要基于UIView去开发

实战用途

画线段

  • 画直线CGContextAddLineToPoint

  • 画虚线CGContextSetLineDash

画三角形

  • CGContextClosePath

画矩形

  • CGContextAddRect

画圆

  • CGContextAddEllipseInRect

画扇形

  • CGContextAddArc

画曲线

  • CGContextAddQuadCurveToPoint

  • CGContextAddCurveToPoint

画特效

  • CGContextSetShadow

  • CGContextSetAlpha

绘制文字

  • drawInRect

绘制图片

  • drawInRect

  • CGContextClip

变换运用(改变画布位置)

  • CGContextTranslateCTM

  • CGContextRotateCTM

  • CGContextScaleCTM

1、CGContextRef之画线段

CGContextRef 具有贯穿全局的效果,我们设置一个全局变量创建 一次 就可以了

虚线

- (void)drawLine1{
//获取图形上下文.或者叫作用域,即画布,他是专门用来保存绘画期间的各种数据的
CGContextRef contextRef = UIGraphicsGetCurrentContext();

//路径设置  
//先设置一个起点  
CGContextMoveToPoint(contextRef, 50, 100);  
//设置终点  
CGContextAddLineToPoint(contextRef, 100, 500);

//设置样式  
//设置线宽  
CGContextSetLineWidth(contextRef, 5.0f);  
//设置线的颜色  
CGContextSetStrokeColorWithColor(contextRef, \[UIColor redColor\].CGColor);

//风格  头部和尾部的处理  
CGContextSetLineCap(contextRef, kCGLineCapRound);

/\*  
 画虚线  
 参数1 作用域  
 参数2 起点的偏移量  
 参数3 指明虚线是如何交替绘制  
 lengths的值{10,10}表示先绘制10个点,再跳过10个点  
 如果把lengths值改为{10, 20, 10},则表示先绘制10个点,跳过20个点,绘制10个点,跳过10个点,再绘制20个点,  
 参数4 实心部分和虚心部分的循环次数  
 \*/  
CGFloat lenths\[\] = {10, 10};  
CGContextSetLineDash(contextRef, 0, lenths, 2);

//渲染  
CGContextStrokePath(contextRef);  

}

效果图

              

2、CGContextRef之画多边形

画三角形

- (void)drawTriangle{
//获取图形上下文
CGContextRef contextRef = UIGraphicsGetCurrentContext();

//设置点  
CGContextMoveToPoint(contextRef, 100, 100);  
CGContextAddLineToPoint(contextRef, 200, 200);  
CGContextAddLineToPoint(contextRef, 100, 200);

//把点封闭起来  
CGContextClosePath(contextRef);

//设置线宽  
CGContextSetLineWidth(contextRef, 3.0f);  
//设置线的颜色  
CGContextSetStrokeColorWithColor(contextRef, \[UIColor redColor\].CGColor);  
//设置填充颜色  
CGContextSetFillColorWithColor(contextRef, \[UIColor greenColor\].CGColor);

// 如果写了多种渲染方式,那么只执行第一种  

// CGContextStrokePath(contextRef);
// CGContextFillPath(contextRef);

CGContextDrawPath(contextRef, kCGPathFillStroke);

}

效果图

画正方形

//获取图形上下文
CGContextRef contextRef = UIGraphicsGetCurrentContext();

CGContextAddRect(contextRef, CGRectMake(100, 100, 100, 100));

//颜色的填充
CGContextSetFillColorWithColor(contextRef, [UIColor redColor].CGColor);
//线宽
CGContextSetLineWidth(contextRef, 4.0f);
CGContextSetStrokeColorWithColor(contextRef, [UIColor blueColor].CGColor);

//渲染
CGContextDrawPath(contextRef, kCGPathFillStroke);

效果图

3、CGContextRef之画曲线

画圆

// 绘制图形上下文
CGContextRef contextRef = UIGraphicsGetCurrentContext();

CGContextAddEllipseInRect(contextRef, CGRectMake(100, 100, 100, 100));

CGContextDrawPath(contextRef, kCGPathFillStroke);

扇形

- (void)drawArc1{

CGContextRef contextRef = UIGraphicsGetCurrentContext();  
/\*  
 参数1:作用域  
 参数2:圆心x坐标  
 参数3:圆心y坐标  
 参数4:半径  
 参数5:开始角度  
 参数6:结束角度  
 参数7:方向,0表示顺时针,1表示逆时针

 \*/  
CGContextAddArc(contextRef, 100, 200, 100, 0, M\_PI\_4, 0);

CGContextSetLineWidth(contextRef, 5.0f);  
CGContextSetFillColorWithColor(contextRef, \[UIColor greenColor\].CGColor);  
CGContextSetStrokeColorWithColor(contextRef, \[UIColor redColor\].CGColor);

// CGContextAddLineToPoint(contextRef, 100, 200);

CGContextDrawPath(contextRef, kCGPathFillStroke);

}

  • (void)drawArc2{
    CGContextRef contextRef = UIGraphicsGetCurrentContext();

    //第一部分
    CGContextMoveToPoint(contextRef, 250, 400);
    CGContextAddArc(contextRef, 250, 400, 100, 0, M_PI_2, 0);
    CGContextSetFillColorWithColor(contextRef, [UIColor blueColor].CGColor);
    CGContextFillPath(contextRef);

    //第二部分
    CGContextMoveToPoint(contextRef, 250, 400);
    CGContextAddArc(contextRef, 250, 400, 100, M_PI_2, M_PI_2/2*3, 0);
    CGContextSetFillColorWithColor(contextRef, [UIColor redColor].CGColor);
    CGContextFillPath(contextRef);

    // 第三部分
    CGContextMoveToPoint(contextRef, 250, 400);
    CGContextAddArc(contextRef, 250, 400, 100, 0, 225*M_PI/180.0, 1);
    CGContextSetFillColorWithColor(contextRef, [UIColor purpleColor].CGColor);
    CGContextFillPath(contextRef);

}

效果图

画曲线

CGContextRef contextRef = UIGraphicsGetCurrentContext();

//起点  
CGContextMoveToPoint(contextRef, 20, 300);  
/\*  
 三阶贝塞尔曲线  
 参数1:作用域  
 参数2:控制点x  
 参数3:控制点y  
 参数4:控制点x  
 参数5:控制点y  
 参数6:终点x  
 参数7:终点y

 - \`CGContextAddQuadCurveToPoint\`  二阶贝塞尔曲线  
 \*/  
CGContextAddCurveToPoint(contextRef, 100, -100, 200, 900, 300, 400);  
 CGContextStrokePath(contextRef);

效果图

4、CGContextRef之画特效

CGContextRef contextRef = UIGraphicsGetCurrentContext();

CGContextAddRect(contextRef, CGRectMake(100, 100, 100, 100));  
CGContextSetFillColorWithColor(contextRef, \[UIColor redColor\].CGColor);  
CGContextSetStrokeColorWithColor(contextRef, \[UIColor greenColor\].CGColor);  
CGContextSetLineWidth(contextRef, 5.0f);

//设置透明度  
//取值范围(0~1,0表示全透明,1是不透明)  
 CGContextSetAlpha(contextRef, 1);

/\*  
 设置阴影  
 参数1:画布  
 参数2:右偏移量  
 参数3:下偏移量  
 参数4:模糊度(0是不模糊,越大越模糊,10就差不多)  
 \*/  
CGContextSetShadow(contextRef, CGSizeMake(10, 10), 10);

CGContextDrawPath(contextRef, kCGPathFillStroke);

效果图

5、CGContextRef之绘制
绘制文字

NSDictionary *dic = @{
NSFontAttributeName:[UIFont systemFontOfSize:15],
NSForegroundColorAttributeName : [UIColor redColor]
};
// 两种的区别drawInRect会自动换行,drawAtPoint:CGPointZero不会自动换行
[text drawInRect:CGRectMake(20, 100, self.bounds.size.width - 40, 100) withAttributes:dic];
// [text drawAtPoint:CGPointMake(20, 200) withAttributes:dic];

绘制图片

- (void)drawImage{
UIImage *image = [UIImage imageNamed:@"image.jpg"];
[image drawInRect:CGRectMake(100, 100, 250, 250)];
// 平铺图像,超出部分会自动剪裁
// [image drawAsPatternInRect:self.bounds];
// 如果实现文字和图片共存,需要将文字写在后面,防止被图片盖住
NSDictionary *dic = @{
NSFontAttributeName:[UIFont systemFontOfSize:15],
NSForegroundColorAttributeName : [UIColor redColor]
};
NSString *text = @"如果实现文字和图片共存,需要将文字写在后面,防止被图片盖住";
[text drawInRect:CGRectMake(100, 300, 250, 100) withAttributes:dic];
}

-(void)clipImage{
/*
思路:先画一个圆,让图片显示在圆的内部,超出的部分不显示。
注意:显示的范围只限于指定的剪切范围,无论往上下文中绘制什么东西,只要超出了这个范围的都不会显示。
*/

CGContextRef contextRef = UIGraphicsGetCurrentContext();  
// 先画一个圆形  
CGContextAddEllipseInRect(contextRef, CGRectMake(100, 400, 200, 200));

// 切割操作  
CGContextClip(contextRef);  
CGContextFillPath(contextRef);

UIImage \*image = \[UIImage imageNamed:@"image.jpg"\];  
\[image drawInRect:CGRectMake(100, 400, 200, 200)\];

}

效果图

6、CGContextRef之图形变换

UIImage *image0 = [UIImage imageNamed:@"image.jpg"];
[image0 drawInRect:CGRectMake(300, 400, 100, 100)];

CGContextRef contextRef = UIGraphicsGetCurrentContext();  
// 移动变换  
//    CGContextTranslateCTM(contextRef, -100, -100);  
/\*\*  
 \*  对象沿着x轴移动-100单位,沿着y轴移动-100单位  
 \*/  
// 多个变换会叠加  
// 缩放  
//    CGContextScaleCTM(contextRef, 0.5, 0.5);

// 获取中心点  

// CGFloat cenX = CGRectGetMidX(self.bounds);
// CGFloat cenY = CGRectGetMidY(self.bounds);
//

// 先移动一下  
//    CGContextTranslateCTM(contextRef, cenX, cenY);  
CGContextTranslateCTM(contextRef, 100+100/2.0, 100+100/2.0);

// 旋转变换  
CGContextRotateCTM(contextRef, M\_PI\_4);  
// 再移动回去  
CGContextTranslateCTM(contextRef, -(100+100/2.0), -(100+100/2.0));

/\*\*  
 \*  旋转可以认为实质是旋转坐标系,会绕着坐标原点旋转,可以先将坐标原点移动到要旋转的图形的中点,然后执行旋转,然后再移动回来,实现绕着图形中心旋转的目的  
 \*/

UIImage \*image = \[UIImage imageNamed:@"image.jpg"\];  
\[image drawInRect:CGRectMake(300, 400, 100, 100)\];

效果图

使用步骤

  • 创建一个 UIBezierPath 对象

  • 用 moveToPoint: 设置初始线段的起点

  • 添加线段,定义一或多个子路径

  • 修改 UIBezierPath 的绘图相关的属性,比如stroke path的属性 lineWidth 和 lineJoinStyle , filled path的属性 usesEvenOddFillRule

常用API
  • 创建矩形bezierPathWithRect

  • 创建矩形内切圆bezierPathWithOvalInRect

  • 圆角矩形bezierPathWithRoundedRect

  • 创建弧形bezierPathWithArcCenter

  • 添加直线addLineToPoint

  • 添加弧形线段addArcWithCenter

  • 添加二阶贝塞尔曲线addQuadCurveToPoint

  • 添加三阶贝塞尔曲线addCurveToPoint

参考链接
Quartz 2D学习(一)简单绘制图形
iOS的UIBezierPath类和贝塞尔曲线

https://www.jianshu.com/p/5e39624efa26

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章