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);
}
复制代码