Quartz 2D编程指南(1) - 概览

Overview of Quartz 2D


       Quartz 2D 是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境,我们可以使用Quartz 2D来实现许多功能,如基本的路径绘制、透明度、描影、绘制阴影、透明层、颜色管理、反锯齿、PDF文档生成和PDF元数据访问。在需要的时候,Quartz 2D还可以借助于图形硬件的功能。
      在Mac OS X中,Quartz 2D可以与其它图形图像技术混合使用,如Core Image、Core Video、OpenGL、 QuickTime。例如,通过使用QuickTime的GraphicsImportCreateCGImage函数,可以用Quartz 2D从一个QuickTime图形导入器中创建一个图像。
      相似的,在iOS,Quartz 2D能够使用各种绘图工作和动画技术,比如:Core Animation,OpenGL ES,UIKit classes.

The Page

      Quartz 2D在图形中使用绘画者模型(painter’s model).在绘画者模型中,每个连续的绘制操作都是一个绘制层(a layer of paint)放置在画布上。我们通常称这个画布为Page.Page上的绘图可以通过额外的绘制操作来叠加更多的绘图。Page上的图像对象只能够通过叠加更多的图形来改变。这个模型允许我们使用小的图元来构建复杂的图形。
     图1-1展示了绘画者模型如何工作。从图中可以看出不同的绘制顺序所产生的效果不一样。

Figure 1-1  The painter’s model

The painter’s model

Page可以是一张纸(如果输出设备是打印机),也可以是虚拟的纸张(如果输出设备是PDF文件),还可以是bitmap图像,这些都根据实际使用的graphics context(绘图上下文)而定。

Drawing Destinations(绘制目标): The Graphics Context

       Graphics Context是一个数据类型(CGContextRef),用于封装Quartz绘制图像到输出设备的信息。设备可以是PDF文件,bitmap或者显示器窗口上。Graphics Context中的信息包括在Page中的图像的图形绘制参数和设备相关的表现形式。Quartz中的所有对象都是绘制到一个Graphics Context中。
       我们可以将Graphics Context想象成为绘制目标,如图1-2所示,当用Quartz绘图时,所有设备相关的特性都包含在我们所使用的Graphics Context中,换句话说,我们可以简单地给Quartz绘图序列指定不同的Graphics Context,就可将相同的图像绘制到不同的设备上,我们不需要任何设备相关的计算,这些都由Quartz替我们完成。

Figure 1-2  Quartz drawing destinations

Quartz drawing destinations

我们可以获得以下graphics contexts:

A bitmap graphics context: A bitmap graphics context允许你使用RGB colors, CMYK colors, or grayscale到位图(bitmap)上。一个位图位图是一个矩形数组(或光栅)的像素,每一个像素都代表着图像的一个点。位图图像也称谓抽样图像。更多详情:Creating a Bitmap Graphics Context。

A PDF graphics context: A PDF graphics context允许你创建PDF文件,在PDF文件中,你的绘制将被存储为一系列的指令。PDF文件和位图(bitmap)的一些重要的区别如下:
1 ):PDF文件不像位图,它可以包含多页。
2 ): 当你绘制页面从 PDF 文档到不同的设备,其结果图像将会根据设备的特征进行优化。
3):PDF文档有着自己独特的分辨率,在不牺牲图像详情的前提下,大小是可以被尽可能的最大和减小。用户能够感知问题和质量和分辨率是相关的。更多详情: Creating a PDF Graphics Context.

A window graphics context :能够让你绘制到窗口上,更多详情: Creating a Window Graphics Context in Mac OS X
A layer context (CGLayerRef):  PostScript graphics context:当你想绘制到 Mac OS X上,你将使内容显示到PostScript graphics context上。更多详情: Obtaining a Graphics Context for Printing

Quartz 2D Opaque Data Types

       除Graphics contexts 之外,Quartz 2D API还定义了一些数据类型,由于这些API是Core Graphics框架的一部分,所以这些数据类型都是以CG开头的。
Quartz 2D使用这些数据类型来创建对象,通过操作这些对象来获取特定的图形,图1-3列举了三个使用Quartz 2D的绘制操作所获得的图像和相关说明:

你能够旋转并显示一个PDF页面
你能够使用一定的模式绘制模式对象。
你能够使用一定的像素填充某个区域,或者实现圆角效果。

Figure 1-3  Opaque data types are the basis of drawing primitives in Quartz 2D
Opaque data types are the basis of drawing primitives in Quartz 2D

Quartz 2D所包含的数据类型如下:

CGPathRef, 用于矢量图形创建路径并进行填充.See Paths.
CGImageRef, 基于提供的相关数据显示位图和位图掩图.See Bitmap Images and Image Masks.
CGLayerRef, 用于显示绘制的layer,并且layer能够被重复绘制(such as for backgrounds or patterns)和离屏渲染. See Core Graphics Layer Drawing
CGPatternRef, 用于重复绘制. See Patterns.
CGShadingRef and CGGradientRef,用于绘制渐变. See Gradients.
CGFunctionRef, 用于定义回调函数,该函数包含一个随机的浮点数,使用这种数据类型当创建渐变阴影效果. See Gradients.
CGColorRef and CGColorSpaceRef,用于通知Quartz理解对应的颜色. See Color and Color Spaces.
CGImageSourceRef and CGImageDestinationRef, 用于在Quartz中移入移出数据. See Data Management in Quartz 2D and Image I/O Programming Guide
CGFontRef, 用于绘制文本. See Text.
CGPDFDictionaryRefCGPDFObjectRefCGPDFPageRefCGPDFStreamCGPDFStringRef, and CGPDFArrayRef, 提供PDF元数据. See PDF Document Creation, Viewing, and Transforming.
CGPDFScannerRef and CGPDFContentStreamRef,解析PDF元数据. See PDF Document Parsing.
CGPSConverterRef, 用于转换PostScript成为PDF,在iOS中不能够使用. See PostScript Conversion.

Graphics States(图形状态)

       Quartz根据修改当前绘图状态的参数来修改绘制的结果。绘制程序根据这些绘图状态来决定如何渲染结果。例如:当你调用设置填充颜色的函数时,你将改变存储在当前绘图状态的颜色值。
       Graphics contexts包含一个绘图状态栈,当Quartz创建一个Graphics contexts时,栈为空。当保存图像状态时,Quartz将当前图形形态的一个副本压入栈中。当还原图形状态是,Quartz将栈顶的图形状态出栈。出栈的状态为当前图形状态。
      可使用函数CGContextSaveGState来保存图形状态,CGContextRestoreGState来还原图形状态。

注意:并不是当前绘制环境的所有方面都是图形状态的元素。如:图形状态不包含当前路径。下面列出了图形状态相关的参数:


Quartz 2D Coordinate Systems

     坐标系统定义是被绘制到Page上的对象的位置及大小范围,如图1-4所示。我们在用户空间坐标系统(user-space coordination system,简称用户空间)中指定图形的位置及大小。坐标值是用浮点数来定义的。

Figure 1-4  The Quartz coordinate system
The Quartz coordinate system


       由于不同的设备有不同的图形功能,所以图像的位置及大小依赖于设备。例如,一个显示设备可能每英寸只能显示少于96个像素,而打印机可能每英寸能显示300个像素。如果在设备级别上定义坐标系统,则在一个设备上绘制的图形无法在其它设备上正常显示。
       Quartz通过使用当前转换矩阵(current transformation matrix, CTM)将一个独立的坐标系统(user space)映射到输出设备的坐标系统(device space),以此来解决设备依赖问题。 CTM是一种特殊类型的矩阵(affine transform, 仿射矩阵),通过平移(translation)、旋转(rotation)、缩放(scale)操作将点从一个坐标空间映射到另外一个坐标空间。
       CTM还有另外一个目的:允许你通过转换来决定对象如何被绘制。例如,为了绘制一个旋转了45度的盒子,我们可以在绘制盒子之前旋转Page的坐标系统。Quartz使用旋转过的坐标系统来将盒子绘制到输出设备中。
        用户空间的点用坐标对(x, y)来表示,(0, 0)表示坐标原点。Quartz中默认的坐标系统是:沿着x轴从左到右坐标值逐渐增大;沿着y轴从下到上坐标值逐渐增大。
      有一些技术在设置它们的graphics context时使用了不同于Quartz的默认坐标系统。相对于Quartz来说,这些坐标系统是修改的坐标系统(modified coordinate system),当在这些坐标系统中显示Quartz绘制的图形时,必须进行转换。最常见的一种修改的坐标系统是原点位于左上角,而沿着y轴从上到下坐标值逐渐增大。我们可以在如下一些地方见到这种坐标系统:

在Mac OS X中,重写过isFlipped方法以返回yes的NSView类的子类
在IOS中,由UIView返回的绘图上下文 
在IOS中,通过调用UIGraphicsBeginImageContextWithOptions函数返回的绘图上下文 

       如果应用程序想以相同的绘制程序在一个UIView对象和PDF Graphics Context上进行绘制,需要做一个变换以使PDF Graphics Context使用与UIView相同的坐标系。要达到这一目的,只需要对PDF的上下文的原点做一个平移(移到左上角)和用-1对y坐标值进行缩放。图1-5显示了这种变换操作:

 

       我们的应用程序负责调整Quartz调用以确保有一个转换应用到上下文中。例如,如果你想要一个图片或PDF正确的绘制到一个Graphics Context中,你的应用程序可能需要临时调整Graphics Context的CTM。在IOS中,如果使用UIImage对象来包裹创建的CGImage对象,可以不需要修改CTM。UIImage将自动进行补偿以适用UIKit的坐标系统。
       注意:如果在iOS上开发与Quartz相关的程序,了解以上的知识点是非常有必要的,但是还不够。在iOS3.2和之后版本中,当UIKit为你的应用程序创建绘图上下文时,也对上下文进行了额外的修改以匹配UIkit的约定。特别是patterns和shadows不被CTM影响,需要单独调整来匹配UIkit坐标系。在这种情况下,没有一个等价的机制让CTM来转换Quartz和UIkit上下文。必须了解到在什么样的上下文中进行绘制,就需要匹配相预期的上下文。

内存管理:对象所有权

       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 Programming Guide

你可能感兴趣的:(Quartz 2D编程指南(1) - 概览)