1.Core Graphics
Core Graphics(Quartz2d) 一套提供2D绘图功能的C语言的API,使用C结构和C函数模拟了一套面向对象的编程机制,并没有Objective-C对象和方法。复制代码
2.CGContextRef
CGContextRef图形上下文“对象”,负责存储绘画状态(例如画笔颜色和线条粗细)和绘制内容所处的内存空间。复制代码
获取CGContextRef:
CGContextRef contextRef = UIGraphicsGetCurrentContext();复制代码
3.Path
CG中path分为不可变路径(CGPathRef)和可变路径(CGMutablePathRef)复制代码
3.1 CGPathRef
创建方法:
//1、根据已存在的路径绘制路径 CGPathCreateCopy(<#CGPathRef _Nullable path#>); //2、根据已存在的路径及transform绘制路径 CGPathCreateCopyByTransformingPath(<#CGPathRef _Nullable path#>, <#const CGAffineTransform * _Nullable transform#>); //3、绘制矩形路径 CGPathCreateWithRect(<#CGRect rect#>, <#const CGAffineTransform * _Nullable transform#>); //4、绘制椭圆(圆是一种特殊的椭圆) CGPathCreateWithEllipseInRect(<#CGRect rect#>, <#const CGAffineTransform * _Nullable transform#>); //5、绘制圆角图形 CGPathCreateWithRoundedRect(<#CGRect rect#>, <#CGFloat cornerWidth#>, <#CGFloat cornerHeight#>, <#const CGAffineTransform * _Nullable transform#>); //6、根据已存在的路径创建一个虚线路径,同时参数`phase', `lengths', and `count'与对应的`CGContextSetLineDash'参数有相同的含义,CGAffineTransform类型,用于在二维空间做旋转,缩放和平移。如transform非空,则在这些参数被添加之前,先进行transform相关的转换。 CGPathCreateCopyByDashingPath(<#CGPathRef _Nullable path#>, <#const CGAffineTransform * _Nullable transform#>, <#CGFloat phase#>, <#const CGFloat * _Nullable lengths#>, <#size_t count#>); //7、根据已存在的路径创建一个路径的描边轮廓,同时参数`lineWidth', `lineCap',`lineJoin', and `miterLimit'与对应的cgcontext参数有相同的含义,CGAffineTransform类型,用于在二维空间做旋转,缩放和平移。如transform非空,则在这些参数被添加之前,先进行transform相关的转换。 CGPathCreateCopyByStrokingPath(<#CGPathRef _Nullable path#>, <#const CGAffineTransform * _Nullable transform#>, <#CGFloat lineWidth#>, <#CGLineCap lineCap#>, <#CGLineJoin lineJoin#>, <#CGFloat miterLimit#>);复制代码
CG中没有ARC机制,调用create、copy方法的对象,需要手动调用该对象的release方法。
3.2 CGMutablePathRef
//1、直接创建 CGPathCreateMutable(); //2、创建已存在路径的一个副本 CGPathCreateMutableCopy(<#CGPathRef _Nullable path#>); //3、创建已存在路径的一个副本,并传入相对已存在的路径CGAffineTransform对象的位移,缩放或者旋转变换 CGPathCreateMutableCopyByTransformingPath(<#CGPathRef _Nullable path#>, <#const CGAffineTransform * _Nullable transform#>);复制代码
ag:
CGMutablePathRef mPath = CGPathCreateMutable();CGPathMoveToPoint(mPath, NULL, 50, 100);CGPathAddLineToPoint(mPath, NULL, 150, 200);CGPathAddLineToPoint(mPath, NULL, 50, 200);复制代码
使用path需要先把path添加到上下文中:
CGContextAddPath(_contextRef, mPath);复制代码
根据需要关闭路径:
CGContextClosePath(_contextRef);复制代码
4.Color
- strokeColor:
CGContextSetRGBStrokeColor(_contextRef, 0.2, 0.8, 0.5, 1);CGContextSetStrokeColor(_contextRef, CGColorGetComponents([UIColor yellowColor].CGColor));复制代码
- fillColor:
CGContextSetRGBFillColor(_contextRef, 0.6, 0.5, 0.4, 1);CGContextSetFillColor(_contextRef, CGColorGetComponents([UIColor greenColor].CGColor));复制代码
5.line
- 线条宽度:
CGContextSetLineWidth(<#CGContextRef _Nullable c#>, <#CGFloat width#>)复制代码
- 线条链接方式:
// 定义线条末端样式 typedef CF_ENUM(int32_t, CGLineCap) { kCGLineCapButt,//指定不绘制端点, 线条结尾处直接结束。(default) kCGLineCapRound,//指定绘制圆形端点, 线条结尾处绘制一个直径为线条宽度的半圆 kCGLineCapSquare//指定绘制方形端点。线条结尾处绘制半个边长为线条宽度的正方形。注意这种形状的端点与“butt”形状的端点十分相似,只是线条比第一种模式长半个线条宽度。 }; // 设置线条连接点的风格 typedef CF_ENUM(int32_t, CGLineJoin) { kCGLineJoinMiter,//接合点为尖角(default) kCGLineJoinRound,//接合点为圆角 kCGLineJoinBevel//接合点为斜角 }; CGContextSetLineCap(<#CGContextRef _Nullable c#>, <#CGLineCap cap#>)复制代码
- 设置虚线:
- (void)pathCreateCopyByDash:(CGPathRef)path{ CGFloat dash[] = {15,20,20,4}; CGAffineTransform transform = CGAffineTransformMakeTranslation(0, 100); /*根据已存在的路径创建一个虚线路径,同时参数`phase', `lengths', and `count'与对应的`CGContextSetLineDash'参数有相同的含义,CGAffineTransform类型,用于在二维空间做旋转,缩放和平移。如transform非空,则在这些参数被添加之前,先进行transform相关的转换。 *参数1:要进行虚线化的不可变路径 *参数2:CGAffineTransform类型转换 *参数3:从lengths数组的第几部分开始绘制虚线 *参数4:C风格的数组 其中为CGFloat值 表示每段虚线的绘制长度 例如传入数组为{10,5},则虚线的先绘制长度为10的实线 在绘制长度为5的空白 在进行循环 *参数5:count是使用数组的长度,也就是说如果数组长度是4,而count是3,那么只使用数组的前三个 */ CGPathRef path1 = CGPathCreateCopyByDashingPath(path, &transform, 1, dash, 3); CGContextSetRGBStrokeColor(_contextRef, 0.2, 0.3, 0.4, 1); CGContextSetLineWidth(_contextRef, 2); CGContextAddPath(_contextRef, path1); CGContextStrokePath(_contextRef); CGPathRelease(path); CGPathRelease(path1);}复制代码
6.绘制
path添加之后需要绘制
- 路径绘制:
CGContextStrokePath(_contextRef);复制代码
- 填充绘制:
CGContextFillPath(_contextRef);复制代码
- 路径+填充绘制:
CGContextDrawPath(_contextRef, kCGPathFillStroke);复制代码
7.state
- 保存上下文状态
CGContextSaveGState(contextRef);复制代码
- 恢复上下文状态
CGContextRestoreGState(contextRef);复制代码
8.context不使用path绘图
// 不实用CGPathRef对象 直接画图 CGContextRef contextRef = UIGraphicsGetCurrentContext(); // line CGPoint points[] = { CGPointMake(100, 100), CGPointMake(150, 200), CGPointMake(50, 200), }; // 数组 int size = sizeof(points)/sizeof(points[0]); CGContextAddLines(contextRef, points, size); [[UIColor grayColor] setFill]; [[UIColor redColor] setStroke]; CGContextSetLineWidth(contextRef, 4); CGContextClosePath(contextRef); CGContextDrawPath(contextRef, kCGPathFillStroke); // 椭圆 CGContextAddEllipseInRect(contextRef, CGRectMake(100, 200, 200, 100)); CGContextSetRGBFillColor(contextRef, 0.5, 0.5, 0.1, 1); CGContextSetStrokeColor(contextRef, CGColorGetComponents([UIColor redColor].CGColor)); CGContextClosePath(contextRef); CGContextDrawPath(contextRef, kCGPathFillStroke); // 扇形 CGPoint center = CGPointMake(300, 300); CGContextMoveToPoint(contextRef, center.x, center.y); CGContextAddArc(contextRef, center.x, center.y, 100, 0, M_PI/1.3, 0); CGContextSetRGBFillColor(contextRef, 0.2, 0.5, 0.8, 1); CGContextSetRGBStrokeColor(contextRef, 0.1, 0.9, 0.2, 1); CGContextClosePath(contextRef); CGContextDrawPath(contextRef, kCGPathFillStroke); // 二次贝塞尔曲线 CGContextMoveToPoint(contextRef, 10, 80); CGContextAddQuadCurveToPoint(contextRef, 300, 200, 10, 320); CGContextSetRGBStrokeColor(contextRef, 0.8, 0.2, 0.4, 1); CGContextStrokePath(contextRef); // 三次贝塞尔曲线 CGContextMoveToPoint(contextRef, 10, 320); CGContextAddCurveToPoint(contextRef, 300, 10, 10, 500, 400, 600); CGContextSetRGBStrokeColor(contextRef, 0.8, 0.6, 0.42, 1); CGContextSetRGBFillColor(contextRef, 0.2, 0.24, 0.8, 1); CGContextClosePath(contextRef); CGContextDrawPath(contextRef, kCGPathFillStroke); // 虚线 CGContextSaveGState(contextRef); CGFloat dash[] = {5,4,3,6}; CGPoint lines[] = { CGPointMake(400, 10), CGPointMake(400, 400), }; CGContextAddLines(contextRef, lines, 2); CGContextSetLineDash(contextRef, 1, dash, 3); [[UIColor redColor] setStroke]; CGContextClosePath(contextRef); CGContextStrokePath(contextRef); CGContextRestoreGState(contextRef); // 添加阴影 // 保存添加阴影之前的效果 CGContextSaveGState(contextRef); CGContextSetShadow(contextRef, CGSizeMake(10, 5), 3); CGContextSetStrokeColor(contextRef, CGColorGetComponents([UIColor purpleColor].CGColor)); //在这里绘制的图像会带有阴影效果 CGContextAddRect(contextRef, CGRectMake(60, 500, 100, 100)); CGContextSetRGBStrokeColor(contextRef, 0.8, 0.6, 0.42, 1); CGContextSetRGBFillColor(contextRef, 0.2, 0.24, 0.8, 1); CGContextClosePath(contextRef); CGContextDrawPath(contextRef, kCGPathFillStroke); // 恢复添加阴影之前的效果 CGContextRestoreGState(contextRef);复制代码
9.渐变
- (void)gradient:(CGContextRef)currentContext{ /* *渐变 */ //保存渐变之前的绘画状态 CGContextSaveGState(currentContext); //绘制渐变剪切路径 UIBezierPath *path1 = [[UIBezierPath alloc] init]; [path1 moveToPoint:CGPointMake(100, 450)]; [path1 addLineToPoint:CGPointMake(250, 450)]; [path1 addLineToPoint:CGPointMake(250, 650)]; [path1 addLineToPoint:CGPointMake(100, 650)]; [path1 closePath]; //是用剪切路径剪裁图形上下文 [path1 addClip]; //绘制渐变 CGFloat locations[4] = {0.0,0.4,0.7,1.0};//三个颜色节点 CGFloat components[16] = {1.0,0.3,0.0,1.0,//起始颜色 0.2,0.8,0.2,1.0,//中间颜色 1.0,1.0,0.5,1.0,//中间颜色 0.8,0.3,0.4,1.0};//终止颜色 //创建RGB色彩空间对象 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 4); //渐变的起点(渐变效果在以起点和终点为轴的直线周边) // CGPoint startPoint = CGPointMake(100, 450); //渐变的终点 // CGPoint endPoint = CGPointMake(250, 650); /*线性渐变 *参数1:当前上下文 *参数2:渐变指针 *参数3,4:渐变的起始和终止位置 *参数5:CGGradientDrawingOptions枚举 typedef CF_OPTIONS (uint32_t, CGGradientDrawingOptions) { kCGGradientDrawsBeforeStartLocation = (1 << 0),//扩展整个渐变到渐变的起点之前的所有点 kCGGradientDrawsAfterEndLocation = (1 << 1)//扩展整个渐变到渐变的终点之后的所有点 }; 0表示既不往前扩展也不往后扩展 */ // CGContextDrawLinearGradient(self.currentContext, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation|kCGGradientDrawsAfterEndLocation); /*径向渐变 *参数1:当前上下文 *参数2:渐变指针 *参数3:渐变的起始圆心 *参数4:渐变的起始半径 *参数5:渐变的终止圆心 *参数6:渐变的终止半径 *参数5:CGGradientDrawingOptions枚举 typedef CF_OPTIONS (uint32_t, CGGradientDrawingOptions) { kCGGradientDrawsBeforeStartLocation = (1 << 0),//扩展整个渐变到渐变的起点之前的所有点 kCGGradientDrawsAfterEndLocation = (1 << 1)//扩展整个渐变到渐变的终点之后的所有点 }; 0表示既不往前扩展也不往后扩展 */ CGContextDrawRadialGradient(currentContext, gradient, CGPointMake(175, 550), 20, CGPointMake(175, 580), 60, 0); //释放创建的C结构对象 CGGradientRelease(gradient); CGColorSpaceRelease(colorSpace); //恢复绘画状态 CGContextRestoreGState(currentContext);}复制代码