iOS 2D绘图详解(Quartz 2D)之概述
2017-04-11 14:00
288 查看
原创Blog,转载请注明出处
http://blog.csdn.net/hello_hwc?viewmode=list
前言:最近在研究自定义控件,由于想要彻底的定制控件的视图还是要继承UIView,虽然对CALayer及其子类很熟练,但是对Quartz 2D这个强大的框架仍然概念模棱两可。于是,决定学习下,暂定7篇文章讲解,会写一些Demo。
官方文档
本文的代码Demo在最后一部分
Quartz 2D属于Core Graphics(所以大多数相关方法的都是以CG开头),是iOS/Mac OSX 提供的在内核之上的强大的2D绘图引擎,并且这个绘图引擎是设备无关的。也就是说,不用关心设备的大小,设备的分辨率,只要利用Quartz
2D,这些设备相关的会自动处理。Quartz 2D能够提供的强大功能如下
透明层(transparency layers)
阴影
基于path的绘图(path-based drawing)
离屏渲染(offscreen rendering)
复杂的颜色处理(advanced color management)
抗锯齿渲染(anti-aliased rendering)
PDF创建,展示,解析(这部分不在这个系列之中)
配合Core Animation, OpenGL ES,UIKit完成复杂的功能
既然提到绘图,那自然有一个容器来包含绘制的结果,然后把这个结果渲染到屏幕上去,而Quartz 2D的容器就是CGContextRef数据模型。这种数据模型是C的结构体,存储了渲染到屏幕上需要的一切信息。
那么,最后 Graphics Context 可以渲染到哪里呢?
Layer
Window
打印机
PDF
Bitmap(图片)
Quartz 2D采用painter’s model,意味着每一次绘制都是一层,然后按照顺序一层层的叠加到画板上。例如
Quartz 2D中的数据类型都是透明的,也就是说用户只需要使用即可,不需要实际访问其中的变量。具体的数据类型包括
CGPathRef 路径类型,用来绘制路径(注意带有ref后缀的一般都是绘制的画板)
CGImageRef,绘制bitmap
CGLayerRef,绘制layer,layer可复用,可离屏渲染
CGPatternRef,重复绘制
CGShadingRef和CGGradientRef,绘制渐变(例如颜色渐变)
CGFunctionRef,定义回调函数,CGShadingRef和CGGradientRef的辅助类型
CGColorRef and CGColorSpaceRef,定义如何处理颜色
CGFontRef,绘制文字
其他类型(pdf这个系列不讲解,所以不会涉及)
在使用quartz 2d进行绘图的时候,经常需要设置颜色,字体,设置context的坐标原点变换,context旋转。这些影响的都是当前绘制状态。Context中利用堆栈的方式来保存绘制状态。调用CGContextSaveGState来保存当前绘制状态的copy到堆栈中,利用CGContextRestoreGState弹出堆栈最顶层的绘制状态,设置为当前的绘制状态。注意,不是所有的参数都会保存,以下表格中的参数会保存
和UIKit的坐标系不一样,Quartz 2D的坐标系是在左下角的。
Quartz利用坐标系的旋转位移等操作来绘制复杂的动画。
但是有两个地方的坐标系是正常的UIKit坐标系
UIView 的context
通过这个方法UIGraphicsBeginImageContextWithOptions返回的context
新建一个UIView的子类,然后重写
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
然后,这样调用
2
1
2
效果
可以看到坐标系是正常的UIKit坐标系
然后,我们在在上面绘制一个文字”Leo”,在上述drawRect的最后添加,
2
1
2
可以看到,绘制是一层一层覆盖的,
最后,我们在右下角绘制一个红心,但是希望红心是反过来的。这里用到了上文的所说的绘制状态堆栈。继续在drawRect的最后添加如下代码
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
效果
这里,初学者可能不懂到底是怎么回事了。我通过图解的方式一步步解释
这行代码把坐标系移动到右下角
如图
接着把坐标系逆时针旋转180度
1
这时候的坐标系
这时候,参考这个坐标系进行绘制,看到的就是反过来的
http://blog.csdn.net/hello_hwc?viewmode=list
前言:最近在研究自定义控件,由于想要彻底的定制控件的视图还是要继承UIView,虽然对CALayer及其子类很熟练,但是对Quartz 2D这个强大的框架仍然概念模棱两可。于是,决定学习下,暂定7篇文章讲解,会写一些Demo。
官方文档
本文的代码Demo在最后一部分
Quartz 2D用来干嘛的?
Quartz 2D属于Core Graphics(所以大多数相关方法的都是以CG开头),是iOS/Mac OSX 提供的在内核之上的强大的2D绘图引擎,并且这个绘图引擎是设备无关的。也就是说,不用关心设备的大小,设备的分辨率,只要利用Quartz2D,这些设备相关的会自动处理。Quartz 2D能够提供的强大功能如下
透明层(transparency layers)
阴影
基于path的绘图(path-based drawing)
离屏渲染(offscreen rendering)
复杂的颜色处理(advanced color management)
抗锯齿渲染(anti-aliased rendering)
PDF创建,展示,解析(这部分不在这个系列之中)
配合Core Animation, OpenGL ES,UIKit完成复杂的功能
画板-The Graphics Context
既然提到绘图,那自然有一个容器来包含绘制的结果,然后把这个结果渲染到屏幕上去,而Quartz 2D的容器就是CGContextRef数据模型。这种数据模型是C的结构体,存储了渲染到屏幕上需要的一切信息。 那么,最后 Graphics Context 可以渲染到哪里呢?
Layer
Window
打印机
Bitmap(图片)
绘制模型
Quartz 2D采用painter’s model,意味着每一次绘制都是一层,然后按照顺序一层层的叠加到画板上。例如
数据类型
Quartz 2D中的数据类型都是透明的,也就是说用户只需要使用即可,不需要实际访问其中的变量。具体的数据类型包括CGPathRef 路径类型,用来绘制路径(注意带有ref后缀的一般都是绘制的画板)
CGImageRef,绘制bitmap
CGLayerRef,绘制layer,layer可复用,可离屏渲染
CGPatternRef,重复绘制
CGShadingRef和CGGradientRef,绘制渐变(例如颜色渐变)
CGFunctionRef,定义回调函数,CGShadingRef和CGGradientRef的辅助类型
CGColorRef and CGColorSpaceRef,定义如何处理颜色
CGFontRef,绘制文字
其他类型(pdf这个系列不讲解,所以不会涉及)
绘制状态
在使用quartz 2d进行绘图的时候,经常需要设置颜色,字体,设置context的坐标原点变换,context旋转。这些影响的都是当前绘制状态。Context中利用堆栈的方式来保存绘制状态。调用CGContextSaveGState来保存当前绘制状态的copy到堆栈中,利用CGContextRestoreGState弹出堆栈最顶层的绘制状态,设置为当前的绘制状态。注意,不是所有的参数都会保存,以下表格中的参数会保存
坐标系
和UIKit的坐标系不一样,Quartz 2D的坐标系是在左下角的。 Quartz利用坐标系的旋转位移等操作来绘制复杂的动画。
但是有两个地方的坐标系是正常的UIKit坐标系
UIView 的context
通过这个方法UIGraphicsBeginImageContextWithOptions返回的context
一个简单的Demo讲解
新建一个UIView的子类,然后重写drawRect
- (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, [UIColor lightGrayColor].CGColor); CGContextFillRect(context, rect);//先填充整个区域 CGRect testRect = CGRectMake(10, 10, 20, 20); CGContextAddRect(context, testRect); CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);//修改画笔颜色 CGContextFillRect(context, testRect);//填充部分区域 }1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
然后,这样调用
LeoDemoView * demoView = [[LeoDemoView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)]; [self.view addSubview:demoView];1
2
1
2
效果
可以看到坐标系是正常的UIKit坐标系
然后,我们在在上面绘制一个文字”Leo”,在上述drawRect的最后添加,
NSString * toDraw = @"Leo"; [toDraw drawAtPoint:CGPointMake(CGRectGetWidth(rect)/2, CGRectGetHeight(rect)/2) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12],NSForegroundColorAttributeName:[UIColor greenColor]}];1
2
1
2
可以看到,绘制是一层一层覆盖的,
最后,我们在右下角绘制一个红心,但是希望红心是反过来的。这里用到了上文的所说的绘制状态堆栈。继续在drawRect的最后添加如下代码
CGContextSaveGState(context); CGContextTranslateCTM(context,rect.size.width,rect.size.height); CGContextRotateCTM(context, M_PI); NSString * redHeart = @"��";//MarkDown 显示不出红心 [redHeart drawAtPoint:CGPointMake(0, 0) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15]}]; CGContextRestoreGState(context); }1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
效果
这里,初学者可能不懂到底是怎么回事了。我通过图解的方式一步步解释
这行代码把坐标系移动到右下角
CGContextTranslateCTM(context,rect.size.width,rect.size.height);
如图
接着把坐标系逆时针旋转180度
CGContextRotateCTM(context, M_PI);1
1
这时候的坐标系
这时候,参考这个坐标系进行绘制,看到的就是反过来的
相关文章推荐
- iOS 2D绘图详解(Quartz 2D)之概述
- iOS 2D绘图详解(Quartz 2D)之概述
- iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)
- iOS 2D绘图详解(Quartz 2D)之Transform(CTM,Translate,Rotate,Scale)
- iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)
- iOS 2D绘图详解(Quartz 2D)之路径(stroke,fill,clip,subpath,blend)
- iOS 2D绘图详解(Quartz 2D)之路径(stroke,fill,clip,subpath,blend)
- iOS 开发 Quartz 2D+ UIBezierPath绘图大全详解
- iOS 2D绘图详解(Quartz 2D)之Bitmap
- iOS 2D绘图详解(Quartz 2D)之Bitmap
- iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)
- iOS Quartz 2D绘图知识详解
- iOS绘图教程--Quartz 2D(CoreGraphics.framework) 详解
- iOS 2D绘图详解(Quartz 2D)之阴影和渐变(Shadow,Gradient)
- iOS Quartz 2D绘图知识详解
- iOS 2D绘图详解(Quartz 2D)之Transform(CTM,Translate,Rotate,Scale)
- iOS 2D绘图详解(Quartz 2D)之阴影和渐变(Shadow,Gradient)
- iOS学习阶段总结-b20120920-Quartz 2D绘图
- 【iOS开发-80】Quartz2D绘图简介:直线/圆形/椭圆/方形以及上下文栈管理CGContextSaveGState/CGContextRestoreGState
- IOS之Quartz2D绘图5.绘制UITableViewCell渐变背景