Quartz2D
一、简介
概述
Quartz 2D是一个二维绘图引擎,同事支持iOS和Mac系统
Quartz 2D能完成的工作
- 绘制图形:线条/三角形/矩形/圆形/弧等
- 绘制文字
- 绘制\生成图片(图像)
- 读取\生成PDF
- 截图\裁剪图片
- 自定义UI控件
Quartz2D须知
- Quartz2D的API是纯C语言的
- Quartz2D的API来自于Core Graphics框架
- 数据类型和函数基本都以CG作为前缀
CGContextRef
CGPathRef
CGContextStrokePath(ctx);
二、图形上下文
概述
- 图形上下文(Graphics Context):是一个CGContextRef类型的数据
- 图形上下文的作用
- 保存绘图信息、绘图状态
- 决定绘制的输出目标(绘制到什么地方去?)
(输出目标可以是PDF文件、Bitmap或者显示器的窗口上)
- 相同的一套绘图序列,指定不同的Graphics Context,就可将相同的图像绘制到不同的目标上
几种类型的Graphics Context:
- Bitmap Graphics Context
- PDF Graphics Context
- Window Graphics Context
- Layer Graphics Context
- Printer Graphics Context
图形上下文栈的操作
1、将当前的上下文copy一份,保存到栈顶(那个栈叫做”图形上下文栈”)
void CGContextSaveGState(CGContextRef c)
2、将栈顶的上下文出栈,替换掉当前的上下文
void CGContextRestoreGState(CGContextRef c)
三、绘图步骤
第一种绘制方法
- 1.获取上下文
- 2.描述路径
- 3.把路径添加到上下文
- 4.渲染上下文
//1.获取上下文
CGContextRef ref = UIGraphicsGetCurrentContext();
//2.描述路径
//创建路径
CGMutablePathRef path = CGPathCreateMutable();
//设置起点
CGPathMoveToPoint(path, NULL, 50, 50);
//给某个点添加一条线
CGPathAddLineToPoint(path, NULL, 100, 100);
//3.把路径添加到上下文
CGContextAddPath(ref, path);
//4.渲染上下文
CGContextStrokePath(ref);
第二种绘制方法(使用封装的函数)
//1.获取上下文
CGContextRef ref = UIGraphicsGetCurrentContext();
//2.设置起点
CGContextMoveToPoint(ref, 100, 100);
//3.给某个点添加一点直线
CGContextAddLineToPoint(ref, 200, 200);
//4.渲染
CGContextStrokePath(ref);
第三种绘制方法(使用UIBezierPath封装的对象)
//1.获得路径
UIBezierPath *path = [[UIBezierPath alloc] init];
//2.设置起点
[path moveToPoint:CGPointMake(20, 20)];
//3.给某点添加一条线
[path addLineToPoint:CGPointMake(100, 100)];
//4.给路径设置属性,lineWidth线宽,lineCapStyle顶角样式,kCGLineJoinRound连接样式
path.lineWidth = 10;
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinRound;
[path stroke];
四、常用的函数
常用拼接路径函数
//新建一个起点
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)
常用绘制路径函数
//Mode参数决定绘制的模式
void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode)
//绘制空心路径
void CGContextStrokePath(CGContextRef c)
//绘制实心路径
void CGContextFillPath(CGContextRef c)
提示:一般以CGContextDraw、CGContextStroke、CGContextFill开头的函数,都是用来绘制路径的
五、自定义View
自定义View的步骤:
- 新建一个类,继承自UIView
- 实现- (void)drawRect:(CGRect)rect方法,然后在这个方法中取得跟当前view相关联的图形上下文
- 绘制相应的图形内容
- 利用图形上下文将绘制的所有内容渲染显示到view上面
drawRect:
- 只有在这个方法才能获取跟View的layer相关联的图形上下文
- 当这个View要显示的时候才会调用drawRect绘制图形(在ViewDidLoad之后,ViewDidAppe之前调用)
六、常见使用
1、矩阵操作
利用矩阵操作,能让绘制到上下文中的所有路径一起发生变化
//缩放
void CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)
//旋转
void CGContextRotateCTM(CGContextRef c, CGFloat angle)
//平移
void CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)
2、图片水印
实现方式:利用Quartz 2D,将水印(LOGO, 文字)画到图片的右下角。
核心实现代码,添加文字水印:
//1.开启位图上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
//2.绘制原来的图片
[image drawAtPoint:CGPointZero];
//3.添加字体水印
NSString *string = @"maple哈哈哈哈";
NSMutableDictionary *attr = [NSMutableDictionary dictionary];
attr[NSFontAttributeName] = [UIFont systemFontOfSize:30];
attr[NSForegroundColorAttributeName] = [UIColor redColor];
[string drawAtPoint:CGPointMake(50, 200) withAttributes:attr];
//4.从位图上下文获得水印图片
UIImage *waterImage = UIGraphicsGetImageFromCurrentImageContext();
//5.关闭上下文
UIGraphicsEndImageContext();
3、图片裁剪
UIImage *image = [UIImage imageNamed:@"阿狸头像"];
//1.开启位图上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
//2.画大圆
CGFloat border = 5;
UIBezierPath *path1 = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width + border * 2, image.size.height + border * 2)];
[[UIColor redColor] set];
[path1 fill];
[path1 stroke];
//2.描述截图的范围
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(border, border, image.size.width, image.size.height)];
[path addClip];
//3.绘制原图
[image drawAtPoint:CGPointZero];
//4.获得图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//5.关闭上下文
UIGraphicsEndImageContext();
self.imageView.image = newImage;
4、屏幕截取
//开启上下文
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0);
//获取上下文
CGContextRef ref = UIGraphicsGetCurrentContext();
//把图片上的图层渲染到上下文
[self.view.layer renderInContext:ref];
//从上下文获得图片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();