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来还原图形状态

可能上面说有一些抽象,下面上代码

 1 - (void)drawRect:(CGRect)rect {
 2
 3     CGContextRef context = UIGraphicsGetCurrentContext();
 4
 5     // 拷贝一份副本,放入绘图状态栈中,这份副本中的绘制信息为空
 6     CGContextSaveGState(context);
 7
 8     // 在当前的上下文中设置绘制信息并进行绘制渲染
 9     CGContextSetLineWidth(context, 3);
10     [[UIColor redColor] set];
11     CGContextMoveToPoint(context, 0, 0);
12     CGContextAddLineToPoint(context, 100, 100);
13     CGContextStrokePath(context);
14
15     // CGContextRestoreGState()将绘图上下文栈弹栈,得到上面拷贝的副本并设置为当前上下文
16     CGContextRestoreGState(context);
17     // 此时的绘制信息完全在副本中设置,不会覆盖上面的参数
18     [[UIColor blackColor] set];
19     CGContextMoveToPoint(context, 10, 0);
20     CGContextAddLineToPoint(context, 50, 80);
21     CGContextStrokePath(context);
22 }

而假如我们不保存图形状态,每次设置绘图信息都在同一个上下文中,便会覆盖上一次的状态,最后渲染时只是一种状态,线的颜色啊,线宽什么的都只是以你最后设置的为准。代码如下

 1 - (void)drawRect:(CGRect)rect {
 2
 3     CGContextRef context = UIGraphicsGetCurrentContext();
 4
 5     // 拷贝一份副本,放入绘图状态栈中,这份副本中的绘制信息为空
 6     CGContextSaveGState(context);
 7
 8     // 在当前的上下文中设置绘制信息并进行绘制渲染
 9     CGContextSetLineWidth(context, 3);
10     [[UIColor redColor] set];
11     CGContextMoveToPoint(context, 0, 0);
12     CGContextAddLineToPoint(context, 100, 100);
13     CGContextStrokePath(context);
14
15     //CGContextRestoreGState(context);
16     // 此时的绘制信息便会覆盖上面的参数
17     [[UIColor blackColor] set];       CGContextSetLineWidth(context, 10);

18     CGContextMoveToPoint(context, 10, 0);

19     CGContextAddLineToPoint(context, 50, 80);
20     CGContextStrokePath(context);
21 }

注意:并不是当前绘制环境的所有方面都是图形状态的元素。如,图形状态不包含当前路径(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/8);// 让坐标系顺时针旋转M_PI/8
    CGContextScaleCTM(context, 1.5, 1.5);// 让坐标系放大1.5倍
    CGContextTranslateCTM(context, 50, 10);// 平移坐标系
    CGContextMoveToPoint(context, 0, 0);
    CGContextAddLineToPoint(context, 100, 100);
    CGContextAddLineToPoint(context, 40, 80);
    CGContextAddLineToPoint(context, 0, 0);
    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值给这些函数。
时间: 2024-10-10 16:09:23

Quartz-2D绘图之概览的相关文章

Quartz 2D 绘图,图像变换

IOS的quartz 2d 绘图,绘图有时候需要进行图形变换. 切记:Quartz 2D的变换都是以CG 开头的,不要和Core Animation的搞混了,Core animatin的是CA开头的. IOS提供了一组可以进行图像变换的API接口,一般的图像变换分为,平移.缩放.旋转. 平移 void CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty); 缩放 void CGContextScaleCTM(CGContext

ios (Quartz 2D绘图)各种绘图方式及相机的使用

一: 具体使用的细节,本人也是参考http://blog.163.com/wkyuyang_001/blog/static/10802122820133190545227/ 下面介绍具体使用Quartz 2D绘图实现画图板功能 .m文件中,dog的实现如连接中所示一样的 <pre name="code" class="objc">#import "drawTestView.h" #import "Dog.h" @i

1 、Quartz 2D绘图基础

Quartz 2D绘图 Quartz 2D绘图的核心API是CGContextRef,该API专门用于绘制各种图形. 关注微信公众号:ioscoding ,分享优质iOS编程技术.by:shuju 1.1  Quartz 2D绘图基础:CGContextRef 使用Quartz 2D绘图的关键步骤有两步:获取CGContextRef:调用CGContextRef的方法进行绘图. 不同场景下获取CGContextRef的方式各不相同,下面介绍iOS开发中最常见的场景下如何获取CGContextRe

Core Graphics框架 利用Quartz 2D绘图

首先,什么是Core Graphics和Quartz 2D? Core Graphics:是基于Quartz 2D绘图引擎的一个C语言的API绘图框架.它也是iOS开发中最基本的框架(Framework)之一.两点原因,第一是该框架是每一个iOS应用最初被建立时,就被系统默认添加的三个框架(Foundation.UIKit.Core Graphics)之一:另一点是,我们平时常见的各种UIKit框架提供的UI控件,实际上都是由Core Graphics进行绘制的. Quartz 2D:是一个绘图

iOS开发——图形编程OC篇&amp;(三)Quartz 2D绘图

绘图 一.简单说明 图形上下文(Graphics Context):是一个CGContextRef类型的数据 图形上下文的作用:保存绘图信息.绘图状态 决定绘制的输出目标(绘制到什么地方去?)(输出目标可以是PDF文件.Bitmap或者显示器的窗口上) 相同的一套绘图序列,指定不同的Graphics Context,就可将相同的图像绘制到不同的目标上. Quartz2D提供了以下几种类型的Graphics Context: Bitmap Graphics Context PDF Graphics

Quartz 2D绘图

(1) 绘图Context是一个绘图的目标对象,定义了绘图的基本属性,如颜色.绘图范围.线宽及样式等. (2)通过UIView会创建Context,可以用类似如下的语句来得到当前的Context. CGContextRef currentContext = UIGraphicsGetCurrentContext(); (3)如果在对其进行修改前想要保存当前状态,可以使用UIGraphicsPushContext: 要恢复保存过的Context,则可用UIGraphicsPopContext. (

绘图与滤镜全面解析--Quartz 2D 、Core Image

绘图与滤镜全面解析 概述 在iOS中可以很容易的开发出绚丽的界面效果,一方面得益于成功系统的设计,另一方面得益于它强大的开发框架.今天我们将围绕iOS中两大图形.图像绘图框架进行介绍:Quartz 2D绘制2D图形和Core Image中强大的滤镜功能. Quartz 2D 基本图形绘制 视图刷新 其他图形上下文 Core Image Quartz 2D 在iOS中常用的绘图框架就是Quartz 2D,Quartz 2D是Core Graphics框架的一部分,是一个强大的二维图像绘制引擎.Qu

Quartz 2D基本绘图

上一节中,我引用别人的文章,详细的讲解了Quartz 2D的基本概念.想了解的,请点击这里.这一节用几个小Demo,来说明Quartz 2D的绘图功能. 1. 我们先定义一个用来绘图的View(DrawView,它继承自UIView),并准备在下面的方法中实现绘图工作. - (void)drawRect:(CGRect)rect; 2. 在主界面上面拖拽一个View,并且将其Class设置为DrawView. 首先,我们来绘制线段,三角形和矩形. 1. 线段:在drawRect:方法中,写入以下

iOS 开发 Quartz 2D+ UIBezierPath绘图大全详解

Quartz 2D 使用大全结构图 UIKIt UIBezierPath Core Graphics OpenGL ES Quartz2D的区别和联系 UIKIt:UIKit中的控件都是基于Core Graphics实现的 UIBezierPath:UIBezierPath属于UIKit,它是苹果对复杂的Core Graphics进行的封装,方便我们用OC语言进行简单的绘图 Core Graphics:是一套基于C语言的API,支持向量图形,线.形状.图案.路径.剃度.位图图像和pdf 内容的绘