Quartz2D是一个二维绘图引擎,同时支持Mac和iOS系统
Quartz2D能绘制图形、绘制文字、绘制图片、生成PDF、裁剪图片等,还可以用来自定义UI控件。
例如画板应用、手势解锁功能、图形报表等都是用Quartz2D实现的。
图形上下文(Graphics Context)是一个CGContextRef类型的数据,它用来保存绘图信息、绘图状态和决定绘制的输出目标(输出目标可以是PDF文件、Bitmap或者显示器的窗口上)。
相同的一套绘图序列,指定不同的图形上下文可将相同的图像绘制到不同的目标上。
Quartz2D提供了一下几种类型的Graphics Context:
当view第一次显示到屏幕上时(被加到UIWindow上显示出来)就会调用drawRect:,调用view的setNeedDisplay或者setNeedDisplayInRect:时也会调用drawRect:
在drawRect:方法中取得上下文后,就可以绘制图形到view上面了。view内部有个layer属性,drawRect:方法中取得的是一个Layer Graphics Context,因此绘制的图形其实是绘制到view的layer上去了。
view之所以能显示东西,是因为它内部有layer。
使用含有“Create”或“Copy”的函数创建的对象,使用完后必须释放,否则将导致内存泄露,使用不含“Create”或“Copy”的函数获取的对象,则不需要释放。
如果retain了一个对象,不再使用时也需要将其release掉。
可以使用Quartz2D的函数来指定retain和release一个对象,例如,如果创建了一个CGColorSpace对象,则使用函数CGColorSpaceRetain和CGColorSpaceRelease来retain和release对象。
也可以使用Core Foundation的CFRetain和CFRelease。注意不能传递NULL值给这些函数。
1 /** 2 * 画三角形 3 */ 4 void drawTriangle() 5 { 6 // 1.获得图形上下文 7 CGContextRef contextRef = UIGraphicsGetCurrentContext(); 8 9 // 2.拼接图形路径 10 // 设置一个起点 11 CGContextMoveToPoint(contextRef, 100, 100); 12 // 添加一条线段到(100,100) 13 CGContextAddLineToPoint(contextRef, 200, 200); 14 // 添加一条线段到(150,40) 15 CGContextAddLineToPoint(contextRef, 150, 40); 16 // 关闭路径(连接起点和终点) 17 CGContextClosePath(contextRef); 18 19 // 3.渲染显示到View上面 20 CGContextStrokePath(contextRef); 21 }
1 /** 2 * 画四边形 3 */ 4 void drawQuadrilateral() 5 { 6 // 1.获得图形上下文 7 CGContextRef contextRef = UIGraphicsGetCurrentContext(); 8 // 2.画矩形 9 CGContextAddRect(contextRef, CGRectMake(100, 100, 150, 100)); 10 // 3.绘制图形 11 CGContextStrokePath(contextRef); 12 }
1 /** 2 * 画圆 3 */ 4 void drawCircle() 5 { 6 // 1.获得图形上下文 7 CGContextRef contextRef = UIGraphicsGetCurrentContext(); 8 // 2.画圆 9 CGContextAddEllipseInRect(contextRef, CGRectMake(100, 100, 100, 100)); 10 // 3.绘制图形 11 CGContextFillPath(contextRef); 12 }
1 /** 2 * 画圆弧 3 */ 4 void drawArc() 5 { 6 // 1.获得图形上下文 7 CGContextRef contextRef = UIGraphicsGetCurrentContext(); 8 9 // 2.画圆弧 10 // x\y : 圆心坐标 11 // radius : 半径 12 // startAngle : 开始角度 13 // endAngle : 结束角度 14 // clockwise : 圆弧的伸展方向(0:顺时针, 1:逆时针) 15 CGContextAddArc(contextRef, 100, 100, 50, 0, M_PI, 1); 16 17 // 3.绘制图形 18 CGContextStrokePath(contextRef); 19 }
1 /** 2 * 画文字 3 */ 4 void drawText() 5 { 6 NSString *str = @"画文字"; 7 // 设置文字属性 8 NSMutableDictionary *attrs = [NSMutableDictionary dictionary]; 9 attrs[NSForegroundColorAttributeName] = [UIColor redColor]; 10 attrs[NSFontAttributeName] = [UIFont systemFontOfSize:20]; 11 12 // 将文字画在某个位置 13 [str drawAtPoint:CGPointMake(100, 100) withAttributes:attrs]; 14 15 // 将文字画在矩形框内 16 // [str drawInRect:CGRectMake(100, 100, 100, 100) withAttributes:attrs]; 17 }
1 /** 2 * 画图片 3 */ 4 void drawImage() 5 { 6 UIImage *image = [UIImage imageNamed:@"1.jpg"]; 7 [image drawaspatternInRect:CGRectMake(100, 100, 100, 100)]; 8 }
1 /** 2 * 图形上下文栈 3 */ 4 void ContextSaveGState() 5 { 6 // 获得图形上下文 7 CGContextRef contextRef = UIGraphicsGetCurrentContext(); 8 9 // 将contextRef拷贝一份放到栈中 10 CGContextSaveGState(contextRef); 11 12 // 设置绘图状态 13 CGContextSetLineWidth(contextRef, 10); 14 [[UIColor redColor] set]; 15 CGContextSetLineCap(contextRef, kCGLineCapRound); 16 17 // 第一根线 18 CGContextMoveToPoint(contextRef, 50, 50); 19 CGContextAddLineToPoint(contextRef, 120, 190); 20 21 // 画线 22 CGContextStrokePath(contextRef); 23 24 // 将栈顶的上下文出栈,替换当前的上下文 25 CGContextRestoreGState(contextRef); 26 27 // 第二根线 28 CGContextMoveToPoint(contextRef, 10, 70); 29 CGContextAddLineToPoint(contextRef, 220, 290); 30 31 // 画线 32 CGContextStrokePath(contextRef); 33 }
1 /** 2 * 矩阵操作 3 */ 4 void contextMatrix() 5 { 6 // 获得图形上下文 7 CGContextRef contextRef = UIGraphicsGetCurrentContext(); 8 9 // 缩小0.5倍(在画线条之前设置) 10 CGContextScaleCTM(contextRef, 0.5, 0.5); 11 // 旋转 12 CGContextRotateCTM(contextRef, M_PI_4); 13 // 移动 14 CGContextTranslateCTM(contextRef, 0, 150); 15 16 // 画矩形 17 CGContextAddRect(contextRef, CGRectMake(100, 100, 100, 100)); 18 CGContextStrokePath(contextRef); 19 }
1 /** 2 * 图片裁剪 3 */ 4 - (void)imageClip 5 { 6 // 1.加载原图 7 UIImage *oldImage = [UIImage imageNamed:@"1.jpg"]; 8 // 2.开启上下文 9 UIGraphicsBeginImageContextWithOptions(oldImage.size, NO, 0.0); 10 // 3.取得当前的上下文 11 CGContextRef contextRef = UIGraphicsGetCurrentContext(); 12 // 4.画圆 13 CGRect circleRect = CGRectMake(0, 0, oldImage.size.width, oldImage.size.height); 14 CGContextAddEllipseInRect(contextRef, circleRect); 15 // 5.按照当前的路径形状(圆形)裁剪,超出这个形状以外的内容都不显示 16 CGContextClip(contextRef); 17 // 6.画图 18 [oldImage drawInRect:circleRect]; 19 // 7.取图 20 UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 21 // 8.结束 22 UIGraphicsEndImageContext(); 23 }
1 /** 2 * 截屏 3 */ 4 - (void)screenCut 5 { 6 // 1.开启上下文 7 UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, 0.0); 8 // 2.将控制器view的layer渲染到上下文 9 [self.layer renderInContext:UIGraphicsGetCurrentContext()]; 10 // 3.取出图片 11 UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 12 // 4.结束上下文 13 UIGraphicsEndImageContext(); 14 }
1 /** 2 * 重绘 3 */ 4 - (void)reDraw 5 { 6 // 重绘(这个方法内部会重新调用drawRect:方法进行绘制) 7 [self setNeedsDisplay]; 8 }
1 /** 2 * 常用属性 3 */ 4 void ContextProperty() 5 { 6 // 获得图形上下文 7 CGContextRef contextRef = UIGraphicsGetCurrentContext(); 8 9 // 设置线段宽度 10 CGContextSetLineWidth(contextRef, 10); 11 // 设置颜色 12 CGContextSetRGBStrokeColor(contextRef, 1, 0, 0, 1); 13 // 设置线段头尾部样式 14 CGContextSetLineCap(contextRef, kCGLineCapRound); 15 // 设置线段转折点的样式 16 CGContextSetLineJoin(contextRef, kCGLineJoinRound); 17 // set : 同时设置为实心和空心颜色 18 // setStroke : 设置空心颜色 19 // setFill : 设置实心颜色 20 [[UIColor whiteColor] set]; 21 22 // 裁剪,裁剪后所画内容只能在裁剪的范围内显示 23 CGContextClip(contextRef); 24 }