Quartz-2D绘图之概览
最近公司新项目需求要把数据图形化,趁着这个机会,重温了下Quarts-2D这个强大的跨平台2D绘图引擎。
一、Quartz概述
1.Quartz 2D是一个二维的绘图引擎,支持iOS和Mac OS平台。
2.功能:可以用来进行基本路径的绘制、透明度、描影、绘制阴影、透明层、颜色管理、反锯齿、PDF文档生成和PDF元数据访问等
二、Quartz操作
1.绘图顺序:Quartz既然是一个绘图引擎,那么画画的先后顺序是非常重要的,下图便展示了它的操作顺序,相信大家都很熟悉这幅图
2.绘制目标:Graphics Context(绘图上下文)
相信很多人刚开始接触到这个单词时跟我一样一头雾水,不明白它指的是什么。按照苹果的官方文档解释说,Graphics Context是种数据类型(CGContextRef),用于封装Quartz绘制图像到输出设备的信息。设备可以是PDF文件、bitmap或者显示器的窗口上。Graphics Context中的信息包括在Page中的图像的图形绘制参数和设备相关的表现形式。Quartz中所有的对象都是绘制到一个Graphics Context中。其实说白了,就是你想在纸上画画,Graphics Context就是那张纸,你想在桌子上画画,Graphics Context就是那张桌子。只不过Graphics Context还保存了你的画笔颜色啊,线条大小啊等一些画图时的参数信息。我们画图时想要画在哪个上面,指定相应的Graphics Context的就可以了。Quartz为我们提供了以下几种类型的Graphics Context
- Bitmap Graphics Context
- PDF Graphics Context
- Window Graphics Context
- Layer Context
- Post Graphics Context
除了Graphics Context这个类型外,Quartz 2D API还定义一些数据类型。由于这些API就是Core Graphics框架的一部分,所以这些数据类型都是以CG开头的,像CGPathRef、CGImageRef之类的,具体的可以参考苹果官方文档,这里不再赘述。
3.图形状态
Quartz通过修改当前图形状态(current graphics state)来修改绘制操作的结果。图形状态包含用于绘制程序的参数。绘制程序根据这些绘图状态来决定如何渲染结果。例如,当你调用设置填充颜色的函数时,你将改变存储在当前绘图状态中的颜色值。
Graphics Context包含一个绘图状态栈。当Quartz创建一个Graphics Context时,栈为空。当保存图形状态时,Quartz将当前图形状态的一个副本压入栈中。当还原图形状态时,Quartz将栈顶的图形状态出栈。出栈的状态成为当前图形状态。
可使用函数CGContextSaveGState来保存图形状态,CGContextRestoreGState来还原图形状态
可能上面说有一些抽象,下面上代码
- (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); // 拷贝一份副本,放入绘图状态栈中,这份副本中的绘制信息为空
CGContextSaveGState(context); // 在当前的上下文中设置绘制信息并进行绘制渲染
CGContextSetLineWidth(context, );
[[UIColor redColor] set];
CGContextMoveToPoint(context, , );
CGContextAddLineToPoint(context, , );
CGContextStrokePath(context); // CGContextRestoreGState()将绘图上下文栈弹栈,得到上面拷贝的副本并设置为当前上下文
CGContextRestoreGState(context);
// 此时的绘制信息完全在副本中设置,不会覆盖上面的参数
[[UIColor blackColor] set];
CGContextMoveToPoint(context, , );
CGContextAddLineToPoint(context, , );
CGContextStrokePath(context);
}
而假如我们不保存图形状态,每次设置绘图信息都在同一个上下文中,便会覆盖上一次的状态,最后渲染时只是一种状态,线的颜色啊,线宽什么的都只是以你最后设置的为准。代码如下
- (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); // 拷贝一份副本,放入绘图状态栈中,这份副本中的绘制信息为空
CGContextSaveGState(context); // 在当前的上下文中设置绘制信息并进行绘制渲染
CGContextSetLineWidth(context, );
[[UIColor redColor] set];
CGContextMoveToPoint(context, , );
CGContextAddLineToPoint(context, , );
CGContextStrokePath(context); //CGContextRestoreGState(context);
// 此时的绘制信息便会覆盖上面的参数
[[UIColor blackColor] set];
CGContextSetLineWidth(context, 10); CGContextMoveToPoint(context, , ); CGContextAddLineToPoint(context, , );
CGContextStrokePath(context);
}
注意:并不是当前绘制环境的所有方面都是图形状态的元素。如,图形状态不包含当前路径(current path)。下面列出了图形状态相关的参数:
- Current transformation matrix (CTM):当前转换矩阵
- Clipping area:裁剪区域
- Line: 线
- Accuracy of curve estimation (flatness):曲线平滑度
- Anti-aliasing setting:反锯齿设置
- Color: 颜色
- Alpha value (transparency):透明度
- Rendering intent:渲染目标
- Color space: 颜色空间
- Text: 文本
- Blend mode:混合模式
4.坐标系统
和我们的UIKit坐标系不同,Quartz是一左下角为原点的,沿着x轴从左到右坐标值逐渐增大;沿着y轴从下到上坐标值逐渐增大。如下图
由于不同的设备有不同的图形功能,所以图像的位置及大小依赖于设备。这就意味着,我们必须对其坐标进行相应的映射变换,好在Quartzt通过CTM可以很轻易的办到这一点。CTM是一种特殊类型的矩阵(affine transform, 仿射矩阵),通过平移(translation)、旋转(rotation)、缩放(scale)操作将点从一个坐标空间映射到另外一个坐标空间。下面上代码
- (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext();
[[UIColor redColor] set];
CGContextRotateCTM(context, M_PI/);// 让坐标系顺时针旋转M_PI/8
CGContextScaleCTM(context, 1.5, 1.5);// 让坐标系放大1.5倍
CGContextTranslateCTM(context, , );// 平移坐标系
CGContextMoveToPoint(context, , );
CGContextAddLineToPoint(context, , );
CGContextAddLineToPoint(context, , );
CGContextAddLineToPoint(context, , );
CGContextStrokePath(context); }
PS:如果你打算在IOS上开发与Quartz相关的程序,了解以上所讨论的是很有用的,但不是必须的。在IOS 3.2及后续的版本中,当UIKit为你的应用程序创建一个绘图上下文时,也对上下文进行了额外的修改以匹配UIKit的约定。特别的,patterns和shadows(不被CTM影响)单独进行调整以匹配UIKit坐标系统。在这种情况下,没有一个等价的机制让CTM来转换Quartz和UIKit的上下文。我们必须认识到在什么样的上下文中进行绘制,并调整行为以匹配上下文的预期。
5.内存管理
Quartz使用Core Foundation内存管理模型(引用计数)。所以,对象的创建与销毁与通常的方式是一样的。在Quartz中,需要记住如下一些规则:
- 如果创建或拷贝一个对象,你将拥有它,因此你必须释放它。通常,如果使用含有”Create”或“Copy”单词的函数获取一个对象,当使用完后必须释放,否则将导致内存泄露。
- 如果使用不含有”Create”或“Copy”单词的函数获取一个对象,你将不会拥有对象的引用,不需要释放它。
- 如果你不拥有一个对象而打算保持它,则必须retain它并且在不需要时release掉。可以使用Quartz 2D的函数来指定retain和release一个对象。例如,如果创建了一个CGColorspace对象,则使用函数CGColorSpaceRetain和CGColorSpaceRelease来retain和release对象。同样,可以使用Core Foundation的CFRetain和CFRelease,但是注意不能传递NULL值给这些函数。
Quartz-2D绘图之概览的更多相关文章
- Quartz 2d绘图
今天看了一下Quartz 2D绘图,我只想说:不要把绘图和动画那些东西当做一个很复杂的东西,其实只要你认真看还是可以理解的.他们并不难.啰嗦了几句,现在直接进入正题: 前提是我们必须新建一个singl ...
- iOS基础 - Quartz 2D绘图的基本步骤
一.使用Quartz 2D绘图的基本步骤 1) 获取上下文context(绘制图形的地方) 2) 设置路径(路径是用来描述形状的) 3) 将路径添加到上下文 4) 设置上下文属性(设置颜色,线宽, ...
- iOS基础 - Quartz 2D绘图
一.Quartz 2D Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境. Quartz 2D以PDF的规范为基础的图形库,用来绘制二维文字和图形,允许相同的绘图指令在任 ...
- Core Graphics框架 利用Quartz 2D绘图
首先,什么是Core Graphics和Quartz 2D? Core Graphics:是基于Quartz 2D绘图引擎的一个C语言的API绘图框架.它也是iOS开发中最基本的框架(Framewor ...
- 关于Quartz 2D绘图的简单使用
Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境,Quartz 2D的API可以实现许多功能,如:基于路径的绘图.透明度.阴影.颜色管理.反锯齿.PDF文档生成和PDF元 ...
- 1.1 Quartz 2D 绘图
本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书” Quartz2D 绘图主要步骤: 1. 获取[图形上下文]对象 —— (拿到草稿纸 ...
- iOS - Quartz 2D 二维绘图
1.Quartz 2D 简介 Quartz 2D 属于 Core Graphics(所以大多数相关方法的都是以 CG 开头),是 iOS/Mac OSX 提供的在内核之上的强大的 2D 绘图引擎,并且 ...
- iOS - Quartz 2D 贝塞尔曲线
1.贝塞尔曲线 贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线.一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支 ...
- iOS_Quartz 2D绘图
目 录: 一.基础知识掌握 二.Quartz 2D绘图基础:CGContextRef实现简单地绘制图形 三.CGContextRef实现文字.图片.基于路径的图形绘制 四.在内存中绘制位图 五.添加 ...
随机推荐
- Java基础—异常处理总结
异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开始,你也许已经知道如何用if...else...来控制异常了,也许是自发的,然而这种控制异常痛苦,同一个异常或者错误如果多个地 ...
- 冒烟测试、α测试、Beta测试、性能测试
“冒烟测试”(也可称为showcase)这一术语描述的是在将代码更改嵌入到产品的源树中之前对这些更改进行验证的过程. 冒烟测试(smoke test)在测试中发现问题,找到了一个Bug,然后开发人员会 ...
- ListControl常用操作汇总
本文根据本人在项目中的应用,来谈谈CListCtrl的部分用法及技巧.当初学习时,查了很多资料,零零碎碎的作了些记录,现在主要是来做个总结,方便以后查阅.主要包括以下十三点内容:基本操作.获取选中行的 ...
- ubuntukylin(64bit)安装推荐
UbuntuKylin是Ubuntu社区中面向中文用户的Ubuntu衍生版本,与麒麟系统没有关系.它是由工信部软件.集成电路促进中心(CSIP).国防科技大学(NUDT)与国际著名开源社区UBUNTU ...
- C++ 把输出结果写入文件/从文件中读取数据
先包含头文文件 #include<fstream> 输出到文件 ofstream fout; //声明一个输出流对象 fout.open("output.txt"); ...
- 使用python爬取P站图片
刚开学时有一段时间周末没事,于是经常在P站的特辑里收图,但是P站加载图片的速度比较感人,觉得自己身为计算机专业,怎么可以做一张张图慢慢下这么low的事,而且这样效率的确也太低了,于是就想写个程序来帮我 ...
- How to effectively work with multiple files in Vim?
Why not use tabs (introduced in Vim 7)? You can switch between tabs with :tabn and :tabp, With :tabe ...
- 容联云通讯_提供网络通话、视频通话、视频会议、云呼叫中心、IM等融合通讯能力开放平台。
容联云通讯_提供网络通话.视频通话.视频会议.云呼叫中心.IM等融合通讯能力开放平台. undefined
- 找回linux丢失的磁盘空间
最近一台服务器空间总是报警,磁盘空间不足. 使用 df 命令查看,磁盘空间耗用接近 100%,将机器上过期的数据以及日志清理掉,但是空间很快又是接近 100%. 使用 du 查看,想找出磁盘空间被耗用 ...
- 用slf4j统一管理日志总结
用slf4j统一管理日志总结 参考网页:http://www.slf4j.org/ 一.使用slf4j统一管理并配置统一使用log4j日志 使用的jar:(slf4j-api-1.7.5.jar,jc ...