Quartz 2D概观

2020-03-09  本文已影响0人  渐z

Core Graphics也称为Quartz 2D,是可用于iOS,tvOS和macOS应用程序开发的高级二维绘图引擎。Quartz 2D提供低级、轻量的2D渲染,无论显示或打印设备如何,其输出保真度均无与伦比。Quartz 2D与分辨率和设备无关。

Quartz 2D API易于使用,并提供对强大功能的访问,例如透明层、基于路径的绘图、离屏渲染、高级颜色管理、抗锯齿渲染以及PDF文档的创建、显示和解析。Quartz 2D会尽可能利用图形硬件的功能。

在Mac OS X中,Quartz 2D可以与所有其他图形技术和成像技术(Co​​re ImageCore VideoOpenGLQuickTime)一起配合使用。可以从QuickTime图形导入器中使用QuickTime函数GraphicsImportCreateCGImage在Quartz中创建图像,有关详细信息请参看QuickTime Framework Reference。Mac OS X中的Moving Data Between Quartz 2D and Core Image描述了如何向Core Image提供图像,Core Image是一个支持图像处理的框架。

同样,在iOS中,Quartz 2D可使用所有可用的图形技术和动画技术,例如Core AnimationOpenGL ESUIKit

可以使用Quartz 2D技术来执行以下任务:

位图(Bitmap),又称栅格图或点阵图,是使用像素阵列(Pixel-array/Dot-matrix点阵)来表示的图像。

页面(The Page)

Quartz 2D使用painter’s model进行成像。 在painter’s model中,每个连续的绘画操作都会应用一层“涂料”到输出“画布”上,这通常被称为一个页面(page)。 可以通过其他绘图操作覆盖更多的涂料来修改页面上的涂料。 在页面上绘制的对象只能通过覆盖更多的涂料来修改。 这种模式使我们可以从少量强大的原函数中构建极其复杂的图像。

下图显示了painter’s model是如何工作的。为了获得下图上半部分中的Result图像,首先绘制左侧的形状,然后绘制实心形状。实心形状覆盖了第一个形状,除了第一个形状的周边之外,其他所有颜色都被遮盖了。下图下半部分中的Result图像则以相反的顺序绘制形状,其是首先绘制实心形状。 如您所见,在painter’s model中,绘图顺序很重要。

the painter’s model

页面可能是一张真实的纸(如果输出设备是打印机),也可能是一张虚拟的纸(如果输出设备是PDF文件),甚至可能是位图图像。页面的确切本质取决于我们使用的特定图形上下文。

绘图目标:图形上下文

图形上下文是不透明的数据类型(CGContextRef),其封装了Quartz用于将图像绘制到输出设备的信息,例如PDF文件,位图或显示器上的窗口。 图形上下文中的信息包含图形绘图参数和页面上涂料的特定于设备的表示。Quartz中的所有对象都被绘制到或包含在图形上下文中。

可以将图形上下文视为绘图目标,如下图所示。当使用Quartz进行绘制时,所有特定于设备的特征都包含在使用的特定类型的图形上下文中。换句话说,只需向相同的Quartz绘制程序提供不同的图形上下文,就可以将同一图像绘制到不同的设备。Quartz会执行任何特定于设备的计算。

Quartz drawing destinations

有以下这些图形上下文可用于我们的应用程序:

Quartz 2D不透明数据类型

除了图形上下文外,Quartz 2D API还定义了各种不透明的数据类型。因为该API是Core Graphics框架的一部分,所以数据类型和对其进行操作的函数都使用CG前缀。

Quartz 2D使用不透明数据类型来创建对象,应用程序可以使用这些对象来实现特定的绘画输出。 下图显示了将绘图操作应用于Quartz 2D提供的三个对象时可以实现的各种结果。例如:

Opaque data types are the basis of drawing primitives in Quartz 2D

Quartz 2D中可用的不透明数据类型包含以下这些:

图形状态

Quartz根据current graphics state中的参数修改绘图操作的结果。图形状态包含会被应用到绘图例程中去的参数,绘制到图形上下文的例程会参考图形状态以确定如何呈现其结果。例如,当调用一个函数来设置填充颜色时,您正在修改存储在当前图形状态中的填充颜色参数值。当前图形状态的其他常用元素包括线宽,当前位置和文本字体大小。

图形上下文包含一个图形状态堆栈。当Quartz创建图形上下文时,堆栈为空。当我们保存图形状态时,Quartz将当前图形状态的副本压入堆栈。 当我们恢复图形状态时,Quartz将图形状态弹出堆栈顶部。被弹出的状态变为当前图形状态。

要保存当前图形状态,请使用CGContextSaveGState函数将当前图形状态的副本推入堆栈。要恢复以前保存的图形状态,请使用CGContextRestoreGState函数将当前图形状态替换为堆栈顶部的图形状态。

请注意,并非当前绘图环境的所有方面都是图形状态的元素。例如,当前路径不被视为图形状态的一部分,因此,当您调用函数CGContextSaveGState时,不会保存当前路径。调用此函数时,保存的图形状态参数包括以下这些:

Quartz 2D 坐标系

下图所示的坐标系定义了用于表示要在页面上绘制的对象的位置和大小的位置范围。可以在用户空间坐标系中,或更简单地,在用户空间中指定图形的位置和大小。坐标被定义为浮点值。

The Quartz coordinate system

由于不同的设备具有不同的基础成像功能,因此必须以与设备无关的方式定义图形的位置和大小。例如,屏幕显示设备可能能够显示每英寸不超过96像素,而打印机可能能够显示每英寸300像素。如果在设备级别(在此示例中为96像素或300像素)定义坐标系,则在该空间中绘制的对象将无法在没有可见畸变的情况下在其他设备上复制。它们将显得太大或太小。

Quartz使用current transformation matrixCTM将一个独立的坐标系(用户空间)映射到输出设备的坐标系(设备空间)来实现设备独立性。矩阵是用于有效描述一组相关方程的数学构造。current transformation matrix是一种特殊类型的矩阵,被称为仿射变换,其通过应用平移,旋转和缩放操作(移动,旋转和调整坐标系大小的计算),将点从一个坐标空间映射到另一个坐标空间。

current transformation matrix还有第二个用处:改变对象的绘制方式。例如,要绘制旋转45度的方框,请在绘制方框之前旋转页面(CTM)的坐标系。Quartz使用旋转后的坐标系绘制到输出设备。

用户空间中的一个点由坐标(x,y)表示,其中x代表该点在水平轴(左和右)上的位置,y代表该点在垂直轴(上和下)上的位置。用户坐标空间的原点是点(0,0)。原点位于页面的左下角,如下图所示。在Quartz的默认坐标系中,x轴上的值随着页面左侧向右侧的移动而增加,y轴上的值随着页面底部向顶部的移动而增加。

某些技术使用与Quartz不同的默认坐标系来设置其图形上下文。相对于Quartz,此类坐标系是已被修改过的坐标系,在执行某些Quartz绘图操作时,必须对这类坐标系进行补偿。最常见的修改过的坐标系将原点放置在上下文的左上角,并将y轴更改为指向页面的底部。您可能会在以下几个地方看到使用此特定坐标系:

UIKit返回具有修改过的坐标系的Quartz绘图上下文的原因是UIKit使用了不同的默认坐标约定。它将transform(变换)应用于它创建的Quartz上下文,以便它们符合其约定。如果您的应用程序希望使用相同的绘图例程来绘制UIView对象和PDF图形上下文(由Quartz创建并使用默认坐标系),则需要应用transform,以便PDF图形上下文收到相同的修改过的坐标系。为了做到这点,需要应用一个将原点平移到PDF上下文的左上角并以-1来缩放y坐标的transform

使用缩放变换取反y坐标会更改Quartz绘图中的某些约定。例如,如果调用CGContextDrawImage将图像绘制到上下文中,则在将图像绘制到目标时,图像会通过transform进行修改。类似地,路径绘制例程接受指定在默认坐标系中沿顺时针或者逆时针方向绘制圆弧的参数。如果修改了坐标系,则结果也会被修改,就像图像在镜子中反射一样。在下图中,将相同的参数传递给Quartz会导致在默认坐标系中是一个顺时针圆弧,以及在y坐标被transform取反后的坐标系中是一个逆时针圆弧。

Modifying the coordinate system creates a mirrored image

您的应用程序可以对创建应用了变换的上下文的任何Quartz调用进行调整。例如,如果您希望将图像或PDF正确地绘制到图形上下文中,则您的应用程序可能需要临时调整图形上下文的CTM。在iOS中,如果使用UIImage对象包装您创建的CGImage对象,则无需修改CTMUIImage对象会自动补偿UIKit应用的修改后的坐标系。

重要:如果打算编写直接针对iOS上Quartz的应用程序,那么上面的讨论对于理解是至关重要的,但这还不够。在iOS 3.2和更高版本上,当UIKit为应用程序创建绘图上下文时,它还会对该上下文进行其他更改以匹配默认的UIKIt约定。特别是,不受CTM影响的图案和阴影会分别进行调整,以使它们的约定与UIKit的坐标系匹配。在这种情况下,应用程序无法使用CTM的等效机制来更改Quartz创建的上下文以匹配UIKit提供的上下文的行为。应用程序必须识别要绘制的上下文属于哪种类型,并调整其行为以符合上下文的期望。

内存管理:对象所有权

Quartz使用对对象进行引用计数的Core Foundation内存管理模式,创建Core Foundation对象后,其开始的引用计数为1。可以通过调用保留对象的函数来增加引用计数,并通过调用释放对象的函数来减少引用计数。当引用计数减为0时,对象会被释放。该模式允许对象安全共享对其他对象的引用。

需要牢记以下一些简单的规则:

上一篇下一篇

猜你喜欢

热点阅读