最近公司新项目需求要把数据图形化,趁着这个机会,重温了下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绘图之概览的更多相关文章

  1. Quartz 2d绘图

    今天看了一下Quartz 2D绘图,我只想说:不要把绘图和动画那些东西当做一个很复杂的东西,其实只要你认真看还是可以理解的.他们并不难.啰嗦了几句,现在直接进入正题: 前提是我们必须新建一个singl ...

  2. iOS基础 - Quartz 2D绘图的基本步骤

    一.使用Quartz 2D绘图的基本步骤 1) 获取上下文context(绘制图形的地方) 2) 设置路径(路径是用来描述形状的) 3)  将路径添加到上下文 4)  设置上下文属性(设置颜色,线宽, ...

  3. iOS基础 - Quartz 2D绘图

    一.Quartz 2D Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境. Quartz 2D以PDF的规范为基础的图形库,用来绘制二维文字和图形,允许相同的绘图指令在任 ...

  4. Core Graphics框架 利用Quartz 2D绘图

    首先,什么是Core Graphics和Quartz 2D? Core Graphics:是基于Quartz 2D绘图引擎的一个C语言的API绘图框架.它也是iOS开发中最基本的框架(Framewor ...

  5. 关于Quartz 2D绘图的简单使用

    Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境,Quartz 2D的API可以实现许多功能,如:基于路径的绘图.透明度.阴影.颜色管理.反锯齿.PDF文档生成和PDF元 ...

  6. 1.1 Quartz 2D 绘图

    本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书”   Quartz2D 绘图主要步骤:   1. 获取[图形上下文]对象 —— (拿到草稿纸 ...

  7. iOS - Quartz 2D 二维绘图

    1.Quartz 2D 简介 Quartz 2D 属于 Core Graphics(所以大多数相关方法的都是以 CG 开头),是 iOS/Mac OSX 提供的在内核之上的强大的 2D 绘图引擎,并且 ...

  8. iOS - Quartz 2D 贝塞尔曲线

    1.贝塞尔曲线 贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线.一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支 ...

  9. iOS_Quartz 2D绘图

    目  录: 一.基础知识掌握 二.Quartz 2D绘图基础:CGContextRef实现简单地绘制图形 三.CGContextRef实现文字.图片.基于路径的图形绘制 四.在内存中绘制位图 五.添加 ...

随机推荐

  1. Colour your Log4Net events in your RichTextBox zz

    You’re most probably here because you have already read my article How to watch your log through you ...

  2. codeforce

    A. Playing with Dice time limit per test 1 second memory limit per test 256 megabytes input standard ...

  3. HDU-2551 竹青遍野

    http://acm.hdu.edu.cn/showproblem.php?pid=2551 妙用for循环. 竹青遍野 Time Limit: 2000/1000 MS (Java/Others)  ...

  4. [App]Xamarin First(Or Last One) App

    这个应用简单得无以复加,主要是熟悉了使用Xamarin Studio进行Android开发的配置和基本流程. 以前未曾具体得做过App开发,现在大致了解了开发所包含的基本元素. 如上图,在Layout ...

  5. C中位域的使用

    一.位域 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一 ...

  6. Vim常用的快捷键列表

    insert: i:insert at now position 在光标之前插入 a:insert append 在光标之后插入 o:下面新建一行插入 s:删除后插入 <<:delete ...

  7. node begining

    node begining */--> pre { background-color: #2f4f4f;line-height: 1.6; FONT: 10.5pt Consola," ...

  8. 软件缺陷分析方法:ODC

    资料 Orthogonal Defect Classification:简要描述. ODC-5-2.pdf :详细说明了ODC对于缺陷属性分类的描述,以及具体应该怎么划分. ODC-5-2-Exten ...

  9. Eclipse非常有用的快捷键

    Eclipse有强大的编辑功能, 工欲善其事,必先利其器, 掌握Eclipse快捷键,可以大大提高工作效率. 小坦克我花了一整天时间, 精选了一些常用的快捷键操作,并且精心录制了动画, 让你一看就会. ...

  10. 大型Web应用运行时 PHP负载均衡指南

    如今,“大型服务器”模式的时代已经过去,我们在运行一些大的Web应用时候,可以使用各种各样的负载均衡技术,这是一种更可行的方法,将使硬件成本降至最低. 过去当运行一个大的web应用时候意味着需要运行一 ...