iOS Quartz 2D绘图知识详解
来源:互联网 发布:vb 字符串拷贝函数 编辑:程序博客网 时间:2024/04/28 07:06
* Quartz*
1. Mac OS X的Darwin核心之上的绘图层,有时候也认为是CoreGraphics。共有两种部分组成Quartz:
2. Quartz Compositor,合成视窗系统,管理和合成幕后视窗影像来建立Mac OS X使用者接口。
3. Quartz 2D,是iOS和Mac OS X环境下的二维绘图引擎。
涉及内容包括:基于路径的绘图,透明度绘图,遮盖,阴影,透明层,颜色管理,防锯齿渲染,生成PDF,以及PDF元数据相关处理。
*一、Quartz 2D的简单介绍**
1. Quartz 2D属于Core Graphics(所以大多数相关方法的都是以CG开头),是iOS/Mac OSX 提供的在内核之上的强大的2D绘图引擎,并且这个绘图引擎是设备无关的。也就是说,不用关心设备的大小,设备的分辨率,只要利用Quartz 2D,这些设备相关的会自动处理。
**2.**Quartz 2D能够提供的强大功能如下:
1. 透明层(transparency layers) 2. 阴影 基于path的绘图(path-based drawing)3. 离屏渲染(offscreen rendering) 4. 复杂的颜色处理(advanced color management) 5. 抗锯齿渲染(anti-aliased rendering)6. PDF创建,展示,解析(这部分不在这个系列之中) 配合Core Animation, OpenGL ES,UIKit完成复杂的功能 画板-The Graphics Context7. 而Quartz 2D的容器就是CGContextRef数据模型。这种数据模型是C的结构体,存储了渲染到屏幕上需要的一切信息。
二、Quartz 2D详解:
Quartz 2D的基本数据类型:
Quartz 2D中的数据类型都是透明的,也就是说用户只需要使用即可,不需要实际访问其中的变量。具体的数据类型包括
1. CGPathRef 路径类型,用来绘制路径(注意带有ref后缀的一般都是绘制的画板)2. CGImageRef,绘制bitmap3. CGLayerRef,绘制layer,layer可复用,可离屏渲染4. CGPatternRef,重复绘制5. CGShadingRef和CGGradientRef,绘制渐变(例如颜色渐变)6. CGFunctionRef,定义回调函数,CGShadingRef和CGGradientRef的辅助类型7. CGColorRef and CGColorSpaceRef,定义如何处理颜色8. CGFontRef,绘制文字
Quartz 2D的坐标
UIKit默认的坐标系统与Quartz不同。在UIKit中,原点位于左上角,y轴正方向为向下。UIView通过将修改Quartz的Graphics Context的CTM[原点平移到左下角,同时将y轴反转(y值乘以-1)]以使其与UIView匹配。这些都是系统自动帮我们完成。
三、直线/矩形
- 基本图形绘制需要的属性
1.获取当前上下文(context)(UIGraphicsGetCurrentContext)2.设置颜色: CGContextSetFillColorWithColor:设置描边颜色 CGContextSetFillColorWithColor:设置填充颜色3. 画的范围 CGContextStrokeRect:描边的范围 CGContextFillRect:填充的范围4.CGContextSetLineWidth:线宽5.CGContextSetLineCap:线顶端的样式6.CGContextSetLineJoin:线拐角的样式7. 线的起始点: CGContextMoveToPoint:起点 CGContextAddLineToPoint:终点8.CGContextFillPath :填充的路径9.CGContextStrokePath:描边的路径
直线、矩形 demo
- (void)drawRect:(CGRect)rect { //1.获得当前context CGContextRef context = UIGraphicsGetCurrentContext(); //设置颜色 (填充色和 描边的颜色) CGContextSetFillColorWithColor(context, [UIColor colorWithWhite:0.8 alpha:1].CGColor); CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor); //设置描边线宽 CGContextSetLineWidth(context, 20); //对矩形进行填色 或 描边 //(注意:如果先描边再填充,由于矩形大小一致,那么描边的线就会被填充的矩形挡住) CGContextFillRect(context, rect); CGContextStrokeRect(context, rect); //----------------------------------------------------------------- //MARK: ------ 实际line和point的代码 // 设置描边颜色 CGContextSetStrokeColorWithColor(context, [UIColor yellowColor].CGColor); CGContextSetLineWidth(context, 8.0);//线的宽度 CGContextSetLineCap(context, kCGLineCapRound);//线的顶端 CGContextSetLineJoin(context, kCGLineJoinRound);//线相交的模式 //----------------------------------------------------------------- //MARK:黄色的 ">" 图形 //移动画笔到哪个点 CGContextMoveToPoint(context,20,20); //画笔画到哪个点 CGContextAddLineToPoint(context, rect.size.width - 20, rect.size.height / 2 - 20); CGContextAddLineToPoint(context, 20, rect.size.height - 20); //根据上下文中的点,成线进行描边 CGContextStrokePath(context); //------------------------------------------------------------------ //MARK: 红色的小的三角的填充 CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor); CGContextMoveToPoint(context, 0, rect.size.height / 2 - 30); CGContextAddLineToPoint(context, 30, rect.size.height / 2); CGContextAddLineToPoint(context, 0, rect.size.height / 2 + 30); CGContextFillPath(context); //虚线效果 //CGContextSetLineDash(context, 1, lengths, 1); //------------------------------------------------------------------ //MARK: 红色虚线效果 CGContextSetStrokeColorWithColor(context,[UIColor redColor].CGColor); CGContextSetLineWidth(context, 1); CGContextMoveToPoint(context, rect.size.width - 20, 20); CGContextAddLineToPoint(context, rect.size.height - 20, rect.size.width - 20); CGFloat lengths[] = {20}; CGContextSetLineDash(context, 1, lengths, 1); CGContextStrokePath(context);}
运行之后的效果:
虚线效果
CGContextSetLineDash参数详解
void CGContextSetLineDash (
CGContextRef _Nullable c,
CGFloat phase,
const CGFloat * _Nullable lengths,
size_t count
);
c 绘制的context,这个不用多说
phase,第一个虚线段从哪里开始,例如传入3,则从第三个单位开始
lengths,一个C数组,表示绘制部分和空白部分的分配。例如传入[2,2],则绘制2个单位,然后空白两个单位,以此重复
count lengths的数量
四、曲线— 圆弧的绘制
Quartz提供了两个方法来绘制圆弧
1. CGContextAddArc,普通的圆弧一部分(以某圆心,某半径,某弧度的圆弧)
2. CGContextAddArcToPoint,用来绘制圆角
- CGContextAddArc
- 结构:
void CGContextAddArc (
CGContextRef _Nullable c,
CGFloat x, // 圆心X坐标
CGFloat y, // 圆心Y坐标
CGFloat radius, // 弧度半径
CGFloat startAngle, // 开始的弧度
CGFloat endAngle, // 结束的弧度
int clockwise //1表示顺时针,0表示逆时针
);
- (void)drawRect:(CGRect)rect { //-------------------------------------------------------------------- //MARK: 画弧 //1.获取图片上下文 CGContextRef context = UIGraphicsGetCurrentContext(); //2.设置弧度及位置 //根据中心点,半径,起始的弧度,最后的弧度,是否顺时针画一个圆弧 CGContextAddArc(context, rect.size.width / 2, rect.size.height / 2, 20, M_PI_4, M_PI, 1); CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); //3.画 CGContextDrawPath(context, kCGPathStroke); // ----------------------------------------------------- //MARK:画有线圈的圆饼 CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);//设置线的颜色 CGContextSetRGBFillColor(context, 0, 0, 1, 1);//设置填充颜色 CGContextSetLineWidth(context, 2); //设置线的宽度 CGContextAddEllipseInRect(context, CGRectMake(10, 30, 60, 60)); //画一个椭圆或者圆 CGContextDrawPath(context, kCGPathFillStroke);}
2.CGContextAddArcToPoint
void CGContextAddArcToPoint (
CGContextRef _Nullable c,
CGFloat x1,
CGFloat y1,
CGFloat x2,
CGFloat y2,
CGFloat radius
);
c context x1,y1和当前点(x0,y0)决定了第一条切线(x0,y0)->(x1,y1) x2,y2和(x1,y1)决定了第二条切线 radius,想切的半径。
也就是说,
绘制一个半径为radius的圆弧,和上述 两条直线都相切。
- (void)drawRect:(CGRect)rect { CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextSetRGBStrokeColor(ctx, 1, 0, 0, 1);//设置线的颜色 CGContextSetRGBFillColor(ctx, 0, 0, 1, 1);//设置填充颜色 CGContextSetLineWidth(ctx, 2); //设置线的宽度 //CGContextAddArcToPoint 先要确定三个点, //1.从哪里开始划线 CGContextMoveToPoint (也就是两条线的交点) //2.第二个点与起始点 确定一条直线 //3.第三个点与第二个点 确定另外一条直线 //画一个圆角矩形 //确定矩形的位置和大小 CGRect rrect = CGRectMake(rect.size.width / 2 - 30, rect.size.height / 2 - 30, 60.0, 60.0); CGFloat radius = 15.0;//半径,半径为正方形一半时,那就可以切成圆形 CGFloat minx = CGRectGetMinX(rrect),//矩形中最小的x midx = CGRectGetMidX(rrect),//矩形中最大x值的一半 maxx = CGRectGetMaxX(rrect);//矩形中最大的x值 CGFloat miny = CGRectGetMinY(rrect),//矩形中最小的Y值 midy = CGRectGetMidY(rrect),//矩形中最大Y值的一半 maxy = CGRectGetMaxY(rrect);//矩形中最大的Y值 CGContextMoveToPoint(ctx, minx, midy);//从点A 开始 //从点A到点B再从点B到点C形成夹角进行切圆 CGContextAddArcToPoint(ctx, minx, miny, midx, miny, radius); CGContextAddArcToPoint(ctx, maxx, miny, maxx, midy, radius); CGContextAddArcToPoint(ctx, maxx, maxy, midx, maxy, radius); CGContextAddArcToPoint(ctx, minx, maxy, minx, midy, radius); CGContextClosePath(ctx); CGContextDrawPath(ctx, kCGPathFillStroke);}
运行效果:
贝塞尔曲线
- (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); CGContextSetLineWidth(context, 4); CGFloat minx = CGRectGetMinX(rect),//矩形中最小的x midx = CGRectGetMidX(rect),//矩形中最大x值的一半 maxx = CGRectGetMaxX(rect);//矩形中最大的x值 CGFloat miny = CGRectGetMinY(rect),//矩形中最小的Y值 midy = CGRectGetMidY(rect),//矩形中最大Y值的一半 maxy = CGRectGetMaxY(rect);//矩形中最大的Y值 //贝塞尔曲线一,两个控制点 红色 CGPoint s = CGPointMake(minx + 10, miny + 10); //起始点 CGPoint e = CGPointMake(maxx - 10, maxy - 10);//终点 CGPoint cp1 = CGPointMake(miny, midy);//控制点1 CGPoint cp2 = CGPointMake(midy, minx);//控制点2 CGContextMoveToPoint(context, s.x, s.y); CGContextAddCurveToPoint(context, cp1.x, cp1.y, cp2.x, cp2.y, e.x, e.y); CGContextStrokePath(context); //贝塞尔曲线二,一个控制点 蓝色 CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor); s = CGPointMake(minx, maxy); e = CGPointMake(maxx, maxy); cp1 = CGPointMake(midx, midy); CGContextMoveToPoint(context, s.x, s.y); CGContextAddQuadCurveToPoint(context, cp1.x, cp1.y, e.x, e.y); CGContextStrokePath(context);}
运行效果
五、颜色渐变
demo
- (void)drawRect:(CGRect)rect { // Drawing code // 创建Quartz上下文 CGContextRef context = UIGraphicsGetCurrentContext(); // 创建色彩空间对象 CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); // 创建起点颜色 CGColorRef beginColor = CGColorCreate(colorSpaceRef, (CGFloat[]){0.01f, 0.5f, 0.01f, 1.0f}); // 创建终点颜色 CGColorRef endColor = CGColorCreate(colorSpaceRef, (CGFloat[]){0.99f, 0.99f, 0.01f, 1.0f}); // 创建颜色数组 const void **values = (const void*[]){beginColor, endColor};//颜色数组 CFArrayRef colorArray = CFArrayCreate( kCFAllocatorDefault, values,//颜色数组 2,//数组的个数 nil// CGGradientCreateWithColors的最后一个locations参数可以传空,这样默认为从0.0到1.0。 ); // 创建渐变对象 CGGradientRef gradientRef = CGGradientCreateWithColors(colorSpaceRef, colorArray, (CGFloat[]){ 0.0f, // 对应起点颜色位置 1.0f // 对应终点颜色位置 }); // 释放颜色数组 CFRelease(colorArray); // 释放起点和终点颜色 CGColorRelease(beginColor); CGColorRelease(endColor); // 释放色彩空间 CGColorSpaceRelease(colorSpaceRef); /* 1.context 上线文 2.gradientRef 颜色数组 3.startPoint 开始位置 4.endPoint 结束位置 5.CGGradientDrawingOptions 当你的起点或者终点不在图形上下文的边缘内时,指定该如何处理。你可以使用你的开始或结束颜色来填充渐变以外的空间。此参数为以下值之一: KCGGradientDrawsAfterEndLocation扩展整个渐变到渐变的终点之后的所有点 KCGGradientDrawsBeforeStartLocation扩展整个渐变到渐变的起点之前的所有点。 0不扩展该渐变。 */ CGPoint startPoint = CGPointMake(0.0f, 0.0f); CGPoint endPoint = CGPointMake(rect.size.width, rect.size.height); CGGradientDrawingOptions options = kCGGradientDrawsAfterEndLocation; CGContextDrawLinearGradient( context, gradientRef, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation// kCGGradientDrawsAfterEndLocation ); // 释放渐变对象 CGGradientRelease(gradientRef);}
效果图
六、多中颜色的渲染
demo
- (void)drawRect:(CGRect)rect { // 创建Quartz上下文 CGContextRef context = UIGraphicsGetCurrentContext(); // 创建色彩空间对象 CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); // 创建渐变对象 CGGradientRef gradientRef = CGGradientCreateWithColorComponents(colorSpaceRef, (CGFloat[]){ 1.0f,0.8f,0.5f,1.0f,//第一个颜色RGB 和透明度 0.6f,0.5f,0.6f,1.0f,//第二个颜色RGB 和透明度 0.3f,0.2f,0.f,1.0f,//第三个颜色RGB 和透明度 .0f,0.0f,0.3f,1.0f }, (CGFloat[]){ 0.0f,0.3f,.6f,1},//颜色渐变的位置 4);//颜色的个数 // 释放色彩空间 CGColorSpaceRelease(colorSpaceRef); // 填充渐变色 CGContextDrawLinearGradient(context, gradientRef, CGPointMake(0.0f, 0.0f), CGPointMake(320.0f, 460.0f), 0); // 释放渐变对象 CGGradientRelease(gradientRef);}
效果
几何图形绘制属性—详解
1.Graphics Context(图层上下文)
- Graphics Context
其实就是表示了一个绘制目标,也就是你打算绘制的地方,它包含绘制系统用于完成绘制指令的绘制参数和设备相关信息。Graphics Context定义了基本的绘制属性,如颜色、裁减区域、线条宽度和样式信息、字体信息、混合模式等。- *获取Graphics Context:
1. Quartz提供的创建函数、Mac OS X框架或IOS的UIKit框架提供的函数。Quartz提供了多种Graphics Context的创建函数,包括bitmap和PDF,我们可以使用这些Graphics Context创建自定义的内容。
2. 在代码中,我们用CGContextRef来表示一个Graphics Context。当获得一个Graphics Context后,可以使用Quartz 2D函数在上下文(context)中进行绘制、完成操作(如平移)、修改图形状态参数(如线宽和填充颜色)等。
查阅的资料
感谢大家在博客或者简书的分享,我在这里做了总结和扩展,仅供大家学习和讨论,如果有什么不对的请大家及时留言评论,谢谢~
本人github账号: 702029772@qq.com
- 博主:zenny_chen http://www.cnblogs.com/zenny-chen/archive/2012/02/23/2364152.html
- 博主:贱见 https://account.aliyun.com/login/login.htm?from_type=yqclub&oauth_callback=https%3A%2F%2Fyq.aliyun.com%2Fusers%2F1482959332945947%3Fspm%3D5176.100239.blogrightarea35932.3.0TK01t%26do%3Dlogin
- iOS Quartz 2D绘图知识详解
- iOS Quartz 2D绘图知识详解
- iOS 绘图 Quartz 2D
- ios--------------Quartz 2D 绘图
- iOS绘图教程--Quartz 2D(CoreGraphics.framework) 详解
- iOS 开发 Quartz 2D+ UIBezierPath绘图大全详解
- iOS 2D绘图详解(Quartz 2D)之概述
- iOS 2D绘图详解(Quartz 2D)之路径(stroke,fill,clip,subpath,blend)
- iOS 2D绘图详解(Quartz 2D)之Transform(CTM,Translate,Rotate,Scale)
- iOS 2D绘图详解(Quartz 2D)之阴影和渐变(Shadow,Gradient)
- iOS 2D绘图详解(Quartz 2D)之Bitmap
- iOS 2D绘图详解(Quartz 2D)之Bitmap
- iOS 2D绘图详解(Quartz 2D)之概述
- Quartz 2D绘图
- Quartz 2D 绘图
- Quartz 2d绘图
- Quartz 2d绘图
- Quartz 2D绘图
- ImageView使用
- BootStrap学习指南
- cake
- 【c++】类和对象
- 保存员工同时保存关联的部门
- iOS Quartz 2D绘图知识详解
- 设计模式-单例模式
- iOS —> UIScrollVeiw
- xilinx-arm-linux交叉编译链 安装总结以及相关资源下载
- iOS CAAnimation之CATransition(自定义转场动画)
- Visual Studio C++ Project 配置
- iOS UIGestureRecognizer (手势的基本知识介绍)
- iOS CAAnimation(动画)知识详解
- JDBC转账,使用事务, 回滚到指定的代码段