绘图我们要用到Core Graphics框架,那么什么是Core Graphics框架?首先我们来介绍一下。
一、 Core Graphics是什么?
Core Graphics Framework是一套基于C的API框架,使用了Quartz作为绘图引擎。它提供了低级别、轻量级、高保真度的2D渲染。该框架可以用于基于路径的绘图、变换、颜色管理、脱屏渲染,模板、渐变、遮蔽、图像数据管理、图像的创建、遮罩以及PDF文档的创建、显示和分析。
二、Core Graphics如何去绘制图呢?
Core Graphics API所有的操作都在一个上下文中进行。所以在绘图之前需要获取该上下文并传入执行渲染的函数中。如果你正在渲染一副在内存中的图片,此时就需要传入图片所属的上下文。获得一个图形上下文是我们完成绘图任务的第一步,你可以将图形上下文理解为一块画布。如果你没有得到这块画布,那么你就无法完成任何绘图操作。当然,有许多方式获得一个图形上下文,这里我介绍两种最为常用的获取方法。
第一种方法就是创建一个图片类型的上下文。调用UIGraphicsBeginImageContextWithOptions函数就可获得用来处理图片的图形上下文。利用该上下文,你就可以在其上进行绘图,并生成图片。调用UIGraphicsGetImageFromCurrentImageContext函数可从当前上下文中获取一个UIImage对象。记住在你所有的绘图操作后别忘了调用UIGraphicsEndImageContext函数关闭图形上下文。
第二种方法是利用cocoa为你生成的图形上下文。当你子类化了一个UIView并实现了自己的drawRect:方法后,一旦drawRect:方法被调用,Cocoa就会为你创建一个图形上下文,此时你对图形上下文的所有绘图操作都会显示在UIView上。
三、Core Graphics绘图时在判断上下问时应该注意什么?
判断一个上下文是否为当前图形上下文需要注意的几点:
1.UIGraphicsBeginImageContextWithOptions函数不仅仅是创建了一个适用于图形操作的上下文,并且该上下文也属于当前上下文。
2.当drawRect方法被调用时,UIView的绘图上下文属于当前图形上下文。
3.回调方法所持有的context:参数并不会让任何上下文成为当前图形上下文。此参数仅仅是对一个图形上下文的引用罢了。
四、具体实现如下
所有画圆、矩形、曲线等图形我们都需要重写-(void)drawRect:(CGRect)rect这个方法。下面来看一下具体每一种图形我们是如何实现的。
1)重写-(void)drawRect:(CGRect)rect方法。
2)在重写方法里面创建一块画布。
//一个不透明类型的Quartz 2D绘画环境,相当于一个画布,你可以在上面任意绘画
CGContextRefcontext =UIGraphicsGetCurrentContext();
1、画圆
//边框圆
CGContextSetRGBStrokeColor(context,1,1,1,1.0);//画笔线的颜色
CGContextSetLineWidth(context,1.0);//线的宽度
//void CGContextAddArc(CGContextRef c,CGFloat x, CGFloat y,CGFloat radius,CGFloat startAngle,CGFloat endAngle, int clockwise)1弧度=180°/π(≈57.3°)度=弧度×180°/π 360°=360×π/180=2π弧度
// x,y为圆点坐标,radius半径,startAngle为开始的弧度,endAngle为结束的弧度,clockwise 0为顺时针,1为逆时针。
CGContextAddArc(context,100,20,15,0,2*PI,0);//添加一个圆
CGContextDrawPath(context,kCGPathStroke);//绘制路径
//填充圆,无边框
CGContextAddArc(context,150,30,30,0,2*PI,0);//添加一个圆
CGContextDrawPath(context,kCGPathFill);//绘制填充
//画大圆并填充颜
UIColor*aColor = [UIColorcolorWithRed:1green:0.0blue:0alpha:1];
CGContextSetFillColorWithColor(context, aColor.CGColor);//填充颜色
CGContextSetLineWidth(context,3.0);//线的宽度
CGContextAddArc(context,250,40,40,0,2*PI,0);//添加一个圆
//kCGPathFill填充非零绕数规则,kCGPathEOFill表示用奇偶规则,kCGPathStroke路径,kCGPathFillStroke路径填充,kCGPathEOFillStroke表示描线,不是填充
CGContextDrawPath(context,kCGPathFillStroke);//绘制路径加填充
效果图:
2)画线或弧线
///*画线及孤线*
////画线
CGPointaPoints[2];//坐标点
aPoints[0] =CGPointMake(100,80);//坐标1
aPoints[1] =CGPointMake(130,80);//坐标2
//CGContextAddLines(CGContextRef c, const CGPoint points[],size_t count)
//points[]坐标数组,和count大小
CGContextAddLines(context, aPoints,2);//添加线
CGContextDrawPath(context,kCGPathStroke);//根据坐标绘制路径
//
////画笑脸弧线
////左
//self.backgroundColor = [UIColor colorWithRed:0.9694 green:1.0 blue:0.9556 alpha:1.0]
CGContextSetRGBStrokeColor(context,0.9694,1.0,0.9556,1.0);//改变画笔颜色
CGContextMoveToPoint(context,140,80);//开始坐标p1
//CGContextAddArcToPoint(CGContextRef c, CGFloat x1, CGFloat y1,CGFloat x2, CGFloat y2, CGFloat radius)
//x1,y1跟p1形成一条线的坐标p2,x2,y2结束坐标跟p3形成一条线的p3,radius半径,注意,需要算好半径的长度,
CGContextAddArcToPoint(context,148,68,156,80,10);
CGContextStrokePath(context);//绘画路径
//右
CGContextMoveToPoint(context,160,80);//开始坐标p1
//CGContextAddArcToPoint(CGContextRef c, CGFloat x1, CGFloat y1,CGFloat x2, CGFloat y2, CGFloat radius)
//x1,y1跟p1形成一条线的坐标p2,x2,y2结束坐标跟p3形成一条线的p3,radius半径,注意,需要算好半径的长度,
CGContextAddArcToPoint(context,168,68,176,80,10);
CGContextStrokePath(context);//绘画路径
//右
CGContextMoveToPoint(context,150,90);//开始坐标p1
//CGContextAddArcToPoint(CGContextRef c, CGFloat x1, CGFloat y1,CGFloat x2, CGFloat y2, CGFloat radius)
//x1,y1跟p1形成一条线的坐标p2,x2,y2结束坐标跟p3形成一条线的p3,radius半径,注意,需要算好半径的长度,
CGContextAddArcToPoint(context,158,102,166,90,10);
CGContextStrokePath(context);//绘画路径
效果图如下:
3、画椭圆
//画椭圆
CGContextAddEllipseInRect(context,CGRectMake(160,180,200,100));//椭圆
CGContextDrawPath(context,kCGPathFillStroke);
效果如图:
4、画三角形
///*画三角形*/
////只要三个点就行跟画一条线方式一样,把三点连接起来
CGPointsPoints[3];//坐标点
sPoints[0] =CGPointMake(100,220);//坐标1
sPoints[1] =CGPointMake(130,220);//坐标2
sPoints[2] =CGPointMake(130,160);//坐标3
CGContextAddLines(context, sPoints,3);//添加线
CGContextClosePath(context);//封起来
CGContextDrawPath(context,kCGPathFillStroke);//根据坐标绘制路径
效果如图:
5、画矩形
///*画圆角矩形*/
floatfw =180;
floatfh =280;
CGContextMoveToPoint(context, fw, fh-20);//开始坐标右边开始
CGContextAddArcToPoint(context, fw, fh, fw-20, fh,10);//右下角角度
CGContextAddArcToPoint(context,120, fh,120, fh-20,10);//左下角角度
CGContextAddArcToPoint(context,120,250, fw-20,250,10);//左上角
CGContextAddArcToPoint(context, fw,250, fw, fh-20,10);//右上角
CGContextClosePath(context);
CGContextDrawPath(context,kCGPathFillStroke);//根据坐标绘制路径
效果如图:
6、画贝塞尔曲线
//二次曲线函数
CGContextMoveToPoint(context,120,300);//设置Path的起点
CGContextAddQuadCurveToPoint(context,190,310,120,390);//设置贝塞尔曲线的控制点坐标和终点坐标
CGContextStrokePath(context);
//三次曲线函数
CGContextMoveToPoint(context,200,300);//设置Path的起点
CGContextAddCurveToPoint(context,250,280,250,400,280,300);//设置贝塞尔曲线的控制点坐标和控制点坐标终点坐标
CGContextStrokePath(context);
效果如图所示: