Quartz2D可以实现裁剪图片功能、涂鸦画板、手势解锁
Quartz2D的API是纯C语言的、API来自于Core Graphics框架,其数据类型和函数基本都以CG作为前缀:
CGContextRef
CGPathRef
CGContextStrokePath(ctx);
图形上下文(Graphics Context):是一个CGContextRef类型的数据。
图形上下文的作用:
相同的一套绘图序列,指定不同的Graphics Context,就可将相同的图像绘制到不同的目标上
Quartz2D提供了以下几种类型的Graphics Context:
Bitmap Graphics Context—>画在图片上[UIImage]《bitmap上下文》
PDF Graphics Context
Window Graphics Context
Layer Graphics Context—>画在view上[UIView]《layer上下文》
Printer Graphics Context
步骤
1、新建一个类,继承自UIView
2、实现- (void)drawRect:(CGRect)rect方法,然后在这个方法中
在drawRect:方法中才能取得跟view相关联的图形上下文
drawRect:方法调用时机:
在drawRect:方法中取得上下文后,就可以绘制东西到view上
View内部有个layer(图层)属性,drawRect:方法中取得的是一个Layer Graphics Context,因此,绘制的东西其实是绘制到view的layer上去了
View之所以能显示东西,完全是因为它内部的layer
1、获得图形上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
2、拼接路径(下面代码是搞一条线段)
CGContextMoveToPoint(ctx, 10, 10);
CGContextAddLineToPoint(ctx, 100, 100);
3、绘制路径
// 绘制line时使用CGContextFillPath无法显示
CGContextStrokePath(ctx); // CGContextFillPath(ctx);
// 新建一个起点
void CGContextMoveToPoint(CGContextRef c, CGFloat x, CGFloat y)
// 添加新的线段到某个点
void CGContextAddLineToPoint(CGContextRef c, CGFloat x, CGFloat y)
// 添加一个矩形
void CGContextAddRect(CGContextRef c, CGRect rect)
// 添加一个椭圆
void CGContextAddEllipseInRect(CGContextRef context, CGRect rect)
// 添加一个圆弧
void CGContextAddArc(CGContextRef c, CGFloat x, CGFloat y, CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)
一般以CGContextDraw、CGContextStroke、CGContextFill开头的函数,都是用来绘制路径的
// Mode参数决定绘制的模式
void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode)
// 绘制空心路径
void CGContextStrokePath(CGContextRef c)
// 绘制实心路径
void CGContextFillPath(CGContextRef c)
// 清除上一次绘制
void CGContextClearRect(CGContextRef c, CGRect rect)
推荐用oc方式,简便
OC方法方式
// 同时设置fill和stroke
[[UIColor blackColor] set];
// 设置fill
[[UIColor blackColor] setFill];
// 设置stroke
[[UIColor blackColor] setStroke];
[[UIColor colorWithRed:252/255.0 green:218/255.0 blue:0 alpha:1.0] set];
C函数方式
// 设置fill
CGContextSetStrokeColor(ctx, CGColorGetComponents([[UIColor redColor] CGColor]));
// 设置stroke
CGContextSetFillColor(ctx, CGColorGetComponents([[UIColor redColor] CGColor]));
CGContextSetRGBFillColor(ctx, 252 / 255.0, 215 / 255.0, 0, 1.0);
绘制文字
NSString *str = @"德国大使馆发地方";
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
// 设置文字大小
dict[NSFontAttributeName] = [UIFont systemFontOfSize:15];
// 设置文字颜色
dict[NSForegroundColorAttributeName] = [UIColor redColor];
// 设置文字背景颜色
dict[NSBackgroundColorAttributeName] = [UIColor greenColor];
// 将文字绘制到指定的范围内, 如果一行装不下会自动换行, 当文字超出范围后就不显示
[str drawInRect:CGRectMake(100, 100, 20, 200) withAttributes:dict];
绘制图片
UIImage *image = [UIImage imageNamed:@"me@2x"];
// 将图片绘制到指定的位置
[image drawAtPoint:CGPointMake(100, 100)];
// 利用drawInRect方法绘制图片到layer, 是通过拉伸原有图片
[image drawInRect:CGRectMake(100, 100, 100, 100)];
// 利用drawAsPatternInRec方法绘制图片到layer, 是通过平铺原有图片
[image drawAsPatternInRect:[UIScreen mainScreen].bounds];
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextAddEllipseInRect(ctx, CGRectMake(20, 20, 50, 50));
// 指定上下文中可以显示内容的范围
// 注意,指定范围(也就是指点剪切的方法一定要在绘制范围之前调用)
CGContextClip(ctx);
CGContextStrokePath(ctx);
UIImage *image = [UIImage imageNamed:@"me@2x"];
[image drawAtPoint:CGPointMake(20, 20)];
// 将当前的上下文copy一份,保存到栈顶(那个栈叫做”图形上下文栈”)
void CGContextSaveGState(CGContextRef c)
// 将栈顶的上下文出栈,替换掉当前的上下文
void CGContextRestoreGState(CGContextRef c)
设置矩阵操作必须在添加绘图信息之前
// 旋转
CGContextRotateCTM(ctx, M_PI_4);
// 缩放
CGContextScaleCTM(ctx, 0.5, 0.5);
// 移动
CGContextTranslateCTM(ctx, 200, 200);
示例:
// 画四边形
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 保存上下文
CGContextSaveGState(ctx);
// 注意:设置矩阵操作必须在添加绘图信息之前
CGContextRotateCTM(ctx, M_PI_4);
// CGContextScaleCTM(ctx, 0.5, 0.5);
// CGContextTranslateCTM(ctx, 0, 150);
CGContextAddRect(ctx, CGRectMake(200, 100, 100, 100));
CGContextStrokePath(ctx);
官方demo:
https://developer.apple.com/library/ios/samplecode/QuartzDemo/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007531
官方说明:
https://developer.apple.com/library/ios/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_paths/dq_paths.html