iOS——Quartz2D(二维图形绘制)
2016-08-31 00:00
232 查看
一、Quartz2D 基本概念和在iOS开发中的价值
1.1 Quartz2D 基本概念
Quartz 2D是一个二维图形绘制引擎,支持ios环境和Mac OS X环境。我们可以使用Quartz 2D API来实现许多功能如基本路径的绘制、透明度、描影、绘制阴影、透明层、颜色管理、反锯齿、PDF文档生成和PDF元数据访问。在需要的时候,Quartz 2D 还可以借助图形硬件的功能。在Mac OS X中,Quartz 2D可以与其它图形图像技术混合使用,如Core Image、Core Video、 OpenGL、QuickTime。例如,通过使用 QuickTime的GraphicsImportCreateCGImage函数,可以用 Quartz从一个 QuickTime图形导入器中创建一个图像。1.2 Quartz2D在iOS开发中的价值
为了便于搭建美观的UI界面,iOS提供了UIKit框架,里面有各种各样的UI控件,比如:UILabel:显示文字;
UIImageView:显示图片;
UIButton:同时显示图片和文字(能点击);
利用UIKit框架提供的控件,拼拼凑凑,能搭建和现实一些简单、常见的UI界面。
但是,有些UI界面极其复杂、而且比较个性化,用普通的UI控件无法实现,这时可以利用Quartz2D技术将控件内部的结构画出来,自定义控件的样子。其实,iOS中大部分控件的内容都是通过Quartz2D画出来的。因此,Quartz2D在iOS开发中很重要的一个价值是:自定义view(自定义UI控件)。
二、UIBezierPath 和 Core Graphics
OS系统本身提供了两套绘图的框架,即UIBezierPath 和 Core Graphics。而前者所属UIKit,其实是对Core Graphics框架关于path的进一步封装,所以使用起来比较简单。但是毕竟Core Graphics更接近底层,所以它更加强大。2.1 UIBezierPath
可以创建基于矢量的路径,例如椭圆或者矩形,或者有多个直线和曲线段组成的形状。使用UIBezierPath,你只能在当前上下文中绘图,所以如果你当前处于UIGraphicsBeginImageContextWithOptions函数或drawRect:方法中,你就可以直接使用UIKit提供的方法进行绘图。如果你持有一个context:参数,那么使用UIKit提供的方法之前,必须将该上下文参数转化为当前上下文。幸运的是,调用UIGraphicsPushContext 函数可以方便的将context:参数转化为当前上下文,记住最后别忘了调用UIGraphicsPopContext函数恢复上下文环境。
我们一般使用UIBezierPath都是在重写的drawRecrt方法这种情形。其绘图的步骤是这样的:
1.重写drawRect方法。但不需要我们自己获取当前上下文context;
2.创建相应图形的UIBezierPath对象,并设置一些修饰属性;
3.渲染,完成绘制。
// 重写drawRect方法 - (void)drawRect:(CGRect)rect { // 创建图形相应的UIBezierPath对象 UIBezierPath* Path = [UIBezierPath bezierPathWithRect:CGRectMake(20, 20, 100, 50)]; // 设置一些修饰属性 // 设置线条宽度 [path setLineWidth:10]; //设置线头的样式:三种样式,kCGLineCapButt, kCGLineCapRound, kCGLineCapSquare [Path.lineCapStyle = kCGLineCapRound]; //设置线条连接点的样式:kCGLineJoinMiter, kCGLineJoinRound,kCGLineJoinBevel [Path.lineJoinStyle = kCGLineCapRound]; // 设置描边的颜色 [[UIColor redColor] setStroke]; [[UIColor whiteColor] setFill]; // 渲染,绘制(描边) [Path stroke]; //绘制(内部填充) [path fill]; }
2.2 Core Graphics
这是一个绘图专用的API族,它经常被称为QuartZ或QuartZ 2D。Core Graphics是iOS上所有绘图功能的基石,包括UIKit。要搞清楚Core Graphics就要搞清楚下面几个问题:
1.绘图需要 CGContextRef
CGContext又叫图形上下文,相当于一块画布,以堆栈形式存放,只有在当前context上绘图才有效。iOS有分多种图形上下文,其中UIView自带提供的在drawRect:方法中通过UIGraphicsGetCurrentContext获取,还有专门为图片处理的context,UIGraphicsBeginImageContext函数生成,还有pdf的context等等。
2.怎么拿到context?
第一种方法是利用cocoa为你生成的图形上下文。当你子类化了一个UIView并实现了自己的drawRect:方法后,一旦
drawRect:方法被调用,Cocoa就会为你创建一个图形上下文,此时你对图形上下文的所有绘图操作都会显示在UIView上。
第二种方法就是创建一个图片类型的上下文。调用
UIGraphicsBeginImageContextWithOptions函数就可获得用来处理图片的图形上下文。利用该上下文,你就可以在其上进行绘图,并生成图片。调用
UIGraphicsGetImageFromCurrentImageContext函数可从当前上下文中获取一个UIImage对象。记住在你所有的绘图操作后别忘了调用
UIGraphicsEndImageContext函数关闭图形上下文。
2.3 绘图上下文相关函数
UIGraphicsGetCurrentContext(): 获取当前绘图上下文,绘图前的第一步,因为所有的绘图都是在上下文完成的,可以理解为获取当前绘图的“画布”。
CGContextSaveGState(): 保存上下文状态,这个函数的作用是将当前图形状态推入堆栈。之后,您对图形状态所做的修改会影响随后的描画操作,但不影响存储在堆栈中的拷贝。
CGContextRestoreGState(): 恢复上下文状态,通过这个函数把堆栈顶部的状态弹出,返回到之前的图形状态。和CGContextSaveGState()配对使用。
CGContextSaveGState()和CGContextRestoreGState()使用举例:整个绘图都是红色,但是中间需要有个图是灰色,这种场景就可以使用这两个函数处理了。
绘图路径相关函数
CGContextMoveToPoint(): 定位到某个点
CGContextAddLineToPoint(): 画线,添加一条直线到一个点
CGContextAddRect(): 画矩形
CGContextAddEllipseInRect(): 内切圆或者椭圆
CGContextAddQuadCurveToPoint(): 一个控制点的贝塞尔曲线
CGContextAddCurveToPoint(): 两个控制点的贝塞尔曲线
CGContextAddArc(): 画曲线
CGContextSetLineDash(): 画虚线
CGContextAddPath(): 画指定的路劲
CGContextClosePath(): 闭合当前路径
绘图设置相关函数
CGContextSetLineWidth(): 设置线条的宽度
CGContextSetStrokeColorWithColor(): 设置线条的颜色(使用UIColor颜色)
CGContextSetStrokeColor(): 设置线条颜色(三色值和透明度)
CGContextSetRGBStrokeColor(): 设置线条颜色(RGB值)
CGContextSetFillColor(): 设置图形填充颜色(三色值和透明度)
CGContextSetFillColorWithColor(): 设置填充颜色(UIColor值)
CGContextSetRGBFillColor():设置填充颜色(RGB值)
CGContextSetAlaha(): 设置透明度
CGContextSetShouldAntialias(): 是否开启抗锯齿
CGContextSetLineCap(): 设置直线端点的样式()
CGContextSetLineJoin(): 设置直线连接点的样式
CGContextSetShadow(): 设置阴影(尺寸和模糊度)
CGContextSetShadowWithColor(): 设置阴影和阴影颜色
图形填充相关函数
CGContextFillRect(): 填充一个矩形
CGContextStrokePath(): 描边
CGContextFillPath(): 只填充不描边
CGContextEOFillPath(): 使用奇偶规则填充
CGContextDrawPath(): 绘制路径(可以选择填充的样式)
三、使用Core Graphics绘图
第一步:获取当前绘图上下文,相当于创建“画布”CGContextRef ctx = UIGraphicsGetCurrentContext();
第二步:设置要绘制的图形
绘图路径
在画线的时候,方法的内部默认创建一个path。它把路径都放到了path里面去。
代码示例:
绘制一条直线的代码:
//直线 // 创建一条路径对象 UIBezierPath *path = [UIBezierPath bezierPath]; // 将画笔移动到某个点 [path moveToPoint:CGPointMake(20, 50)]; // 绘制一条直线到某个点 [path addLineToPoint:CGPointMake(300, 50)]; [path addLineToPoint:CGPointMake(160, 200)]; // [path addLineToPoint:CGPointMake(20, 50)]; // 闭合路径 [path closePath];
绘制画矩形,圆角矩形,内切的椭圆的代码:
// 画矩形 // UIBezierPath *path = [UIBezierPath bezierPathWithRect:rect]; // 圆角矩形 // UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:20]; // 内切的椭圆、圆形 UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect];
绘制画弧线的代码:
#pragma mark - 画弧线 - (void)drawArc { CGPoint center = self.center; /** Center: 圆心 radius: 半径 startAngle: 起始弧度 endAngle: 终点弧度 clockwise:是否顺时针 **/ UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:150 startAngle:0 endAngle: M_PI_2 clockwise:YES]; path.lineWidth = 5; [path addLineToPoint:center]; [path closePath]; [[UIColor redColor] setStroke]; [[UIColor whiteColor] setFill]; [path stroke]; [path fill]; }
绘制贝赛尔曲线的代码:
[path moveToPoint:beginPoint]; //一个控制点的贝塞尔曲线 [path addQuadCurveToPoint:endPoint controlPoint:controlPoint]; CGPoint beginPoint_1 = CGPointMake(50, 300); CGPoint endPoint_1 = CGPointMake(150, 300); CGPoint controlPoint_1 = CGPointMake(75, 400); CGPoint controlPoint_2 = CGPointMake(125, 200); [path moveToPoint:beginPoint_1]; //两个控制点的贝塞尔曲线 [path addCurveToPoint:endPoint_1 controlPoint1:controlPoint_1 controlPoint2:controlPoint_2]; //拼接两条路径 UIBezierPath *subPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(170, 300, 200, 200)]; [path appendPath:subPath]; //移除所有的路径 // [path removeAllPoints]; [path stroke]; }
绘制画波线的代码:
// 画波线 - (void)drawBezierPaths { UIBezierPath *path = [UIBezierPath bezierPath]; [[UIColor redColor] setStroke]; path.lineWidth = 3; // 当前视图的宽高 CGFloat screenWidth = CGRectGetWidth(self.bounds); CGFloat screenHeight = CGRectGetHeight(self.bounds); // 每一个曲线的宽度 CGFloat width = screenWidth / 10; for (int i = 0; i < 10; i++) { // 控制点的Y坐标 CGFloat controlPoint_Y = 0; if (i % 2 == 0) { controlPoint_Y = screenHeight / 2 - 100; } else { controlPoint_Y = screenHeight / 2 + 100; } CGPoint beginPoint = CGPointMake(i * width, screenHeight / 2); CGPoint endPoint = CGPointMake(beginPoint.x + width, screenHeight / 2); CGPoint controlPoint = CGPointMake((width / 2)+ (i * width), controlPoint_Y); [path moveToPoint:beginPoint]; [path addQuadCurveToPoint:endPoint controlPoint:controlPoint]; } [path stroke]; }
四、总结
Core Graphics是iOS绘图的基础框架,UIKit是对它的一个封装,以使绘制常见图形更加方便,比如
UIBezierPath就可以直接绘制
圆角矩形,而
Core Graphics要通过不同的方法配合使用才能实现,iOS应用开发中的大部分绘制需求应该都可以通过
UIKit的绘制方法实现。
相关文章推荐
- iOS——Quartz2D(二维图形绘制)
- iOS——Quartz2D(二维图形绘制)
- iOS——Quartz2D(二维图形绘制)
- iOS Quartz2D基本图形绘制
- iOS:quartz2D绘图(给图形绘制阴影)
- iOS:quartz2D绘图(绘制渐变图形)
- iOS开发UI篇—Quartz2D使用(绘制基本图形)
- IOS学习笔记 运用Quartz 2D框架绘制常见的图形(2)
- iOS开发UI篇—Quartz2D使用(绘制基本图形)
- iOS-UI -- Quartz2D绘制基本图形
- iOS开发UI之Quartz2D使用(绘制基本图形)
- iOS上使用Quartz 2D绘制简单图形
- iOS 图形绘制<一> 利用Quartz2D绘制直线
- iOS边练边学--(Quartz2D)基本图形的绘制#附加自定义进度控件的练习
- iOS 绘制渐变图形 Quartz2D 之Swift
- iOS Quartz2D 绘制简单图形--线,圆,弧线,贝塞尔曲线,文字
- ios-day14-01(使用Quartz 2D绘制基本图形——线、三角形、矩形、圆、圆弧、扇形、文字、图片等)
- iOS Quartz2D绘制简单图形
- IOS之Quartz2D绘图1.简单几何图形绘制
- iOS开发系列--Quartz 2D绘制2D图形和Core Image中强大的滤镜功能