Quartz 2D 编程指南四:颜色和颜色空间

1.Color and Color Spaces(颜色和颜色空间)

Devices (displays, printers, scanners, cameras) don’t treat color the same way; each has its own range of colors that the device can produce faithfully. A color produced on one device might not be able to be produced on another device.

设备(显示器,打印机,扫描仪,相机)处理颜色的方式是不同的, 每种设备都有其所支持的颜色范围。 一种设备上能支持的颜色可能在其他设备上无法支持。

To work with color effectively and to understand the Quartz 2D functions for using color spaces and color, you should be familiar with the terminology discussed in Color Management Overview. That document discusses color perception, color values, device-independent and device color spaces, the color-matching problem, rendering intent, color management modules, and ColorSync.

为了有效地使用颜色并了解使用颜色空间和颜色的Quartz 2D功能,您应该熟悉色彩管理概述中讨论的术语。 该文件讨论了颜色感知,颜色值,设备无关和设备颜色空间,颜色匹配问题,渲染意图,颜色管理模块和ColorSync。

In this chapter, you’ll learn how Quartz represents color and color spaces, and what the alpha component is. This chapter also discusses how to:

  • Create color spaces
  • Create and set colors
  • Set rendering intent

在本章中,您将了解Quartz如何处理颜色和颜色空间,以及Alpha组件是什么。 本章还讨论了:

  • 如何创建颜色空间
  • 如何创建和设置颜色
  • 设置渲染意图

2.About Color and Color Spaces(关于颜色和颜色空间)

A color in Quartz is represented by a set of values. The values are meaningless without a color space that dictates how to interpret color information. For example, the values in Table 4-1 all represent the color blue at full intensity. But without knowing the color space or the allowable range of values for each color space, you have no way of knowing which color each set of values represents.

Quartz中的颜色由一组值表示。没有指定颜色空间而设置颜色信息数值是毫无意义的。例如,表4-1中的值全部表示全亮度的蓝色。但是,如果不知道对应的颜色空间和值域,我们就无法确定这组值所表示的颜色。

Table 4-1 Color values in different color spaces

Values Color space Components
240 degrees, 100%, 100% HSB Hue, saturation, brightness
0, 0, 1 RGB Red, green, blue
1, 1, 0, 0 CMYK Cyan, magenta, yellow, black
1, 0, 0 BGR Blue, green, red

If you provide the wrong color space, you can get quite dramatic differences, as shown in Figure 4-1. Although the green color is interpreted the same in BGR and RGB color spaces, the red and blue values are flipped.

如果我们错误地使用了颜色空间,我们就会得到错误的颜色。

Figure 4-1  Applying a BGR and an RGB color profile to the same image
Figure 4-1 Applying a BGR and an RGB color profile to the same image

Color spaces can have different numbers of components. Three of the color spaces in the table have three components, while the CMYK color space has four. Value ranges are relative to that color space. For most color spaces, color values in Quartz range from 0.0 to 1.0, with 1.0 meaning full intensity. For example, the color blue at full intensity, specified in the RGB color space in Quartz, has the values (0, 0, 1.0). In Quartz, color also has an alpha value that specifies the transparency of a color. The color values in Table 4-1 don’t show an alpha value.

颜色空间可以有不同数量的组件。表中的三个颜色空间有三个组件,而CMYK的颜色空间有四个。值范围是相对于该颜色空间。对于大多数颜色空间,Quartz中的颜色值范围为0.0到1.0,其中1.0表示全强度。例如,Quartz中RGB颜色空间中指定的全强度颜色为蓝色,值为(0,0,1.0)。在Quartz中,颜色也有一个alpha值,用于指定颜色的透明度。表4-1中的颜色值不显示Alpha值。

2.The Alpha Value(Alpha值)

The alpha value is the graphics state parameter that Quartz uses to determine how to composite newly painted objects to the existing page. At full intensity, newly painted objects are opaque. At zero intensity, newly painted objects are invisible. Figure 4-2 shows five large rectangles, drawn using alpha values of 1.0, 0.75, 0.5, 0.1, and 0.0. As the large rectangle becomes transparent, it exposes a smaller, opaque red rectangle drawn underneath.

Alpha值是Quartz用于确定如何将新绘制的对象复合到现有页面的图形状态参数。在全部强度下,新绘的物体是不透明的。在零强度下,新绘的物体是不可见的。图4-2显示了使用1.0,0.75,0.5,0.1和0.0的alpha值绘制的五个大矩形。随着大矩形变得透明,在其下方绘制的不透明红色矩形逐渐显现。

Figure 4-2  A comparison of large rectangles painted using various alpha values
Figure 4-2 A comparison of large rectangles painted using various alpha values

You can make both the objects on the page and the page itself transparent by setting the alpha value globally in the graphics context before painting. Figure 4-3 compares a global alpha setting of 0.5 with the default value of 1.0.

您可以通过在绘制之前在图形上下文中设置全局alpha值,使页面上的对象和页面本身都透明。图4-3将全局alpha设置为0.5,默认值为1.0。

Figure 4-3  A comparison of global alpha values
Figure 4-3 A comparison of global alpha values

In the normal blend mode (which is the default for the graphics state) Quartz performs alpha blending by combining the components of the source color with the components of the destination color using the formula:

destination = (alpha * source) + (1 - alpha) * destination

在正常混合模式(这是图形状态的默认模式)中,Quartz通过使用以下公式来混合源颜色和目标颜色的组件:

destination = (alpha * source) + (1 - alpha) * destination

where source is one component of the new paint color and destination is one component of the background color. This formula is executed for each newly painted shape or image.

其中源颜色是新绘制的颜色,目标颜色是背景颜色。该公式用于新绘制的形状和图像。

For object transparency, set the alpha value to 1.0 to specify that objects you draw should be fully opaque; set it to 0.0 to specify that newly drawn objects are fully transparent. An alpha value between 0.0 and 1.0 specifies a partially transparent object. You can supply an alpha value as the last color component to all routines that accept colors. You can also set the global alpha value using the CGContextSetAlpha function. Keep in mind that if you set both, Quartz multiplies the alpha color component by the global alpha value.

对于对象透明度,将alpha值设置为1.0,以指定您绘制的对象应完全不透明; 将其设置为0.0以指定新绘制的对象是完全透明的。 0.0和1.0之间的alpha值指定部分透明的对象。 您可以为接受颜色的所有例程提供Alpha值作为最后一个颜色分量。 您还可以使用CGContextSetAlpha函数设置全局alpha值。 请记住,如果您同时设置了这两个,Quartz混合全局alpha值和对象alpha值。

To allow the page itself to be fully transparent, you can explicitly clear the alpha channel of the graphics context using the CGContextClearRect function, as long as the graphics context is a window or bitmap graphics context. You might want to do this when creating a transparency mask for an icon, for example, or to make the background of a window transparent.

为了让page完全透明,我们可以调用CGContextClearRect函数来清除图形上下文的alpha通道。当我们为图标创建透明遮照或者创建透明窗口时都可以采取这种方式。

3.Creating Color Spaces(创建颜色空间)

Quartz supports the standard color spaces used by color management systems for device-independent color spaces and also supports generic, indexed, and pattern color spaces. Device-independent color spaces represent color in a way that is portable between devices. They are used for the interchanges of color data from the native color space of one device to the native color space of another device. Colors in a device-independent color space appear the same when displayed on different devices, to the extent that the capabilities of the device allow. For that reason, device-independent color spaces are your best choice for representing color.

Quartz支持颜色管理系统使用的标准颜色空间,也支持通用颜色空间,索引颜色空间和模式颜色空间。设备颜色空间以一种简便的方法在不同的设备上表示颜色。它用于在不同设备间的本地颜色空间转换颜色数据。设备依赖颜色空间的颜色在不同设备上显示的颜色是一样的,它扩展了设备的能力。基于此,设备依赖颜色空间是显示颜色时最好的选择。

Applications that have precise color requirements should always use a device-independent color space. A common device independent color space is the generic color space. Generic color spaces let the operating system provide the best color space for your application. Drawing to the display looks as good as printing the same content to a printer.

对颜色精确度高的应用程序应始终使用与设备无关的颜色空间。 常见的设备独立色彩空间是通用色彩空间。 通用色彩空间让操作系统为应用程序提供最佳色彩空间。 它能使在显示器上的显示效果和在打印机上的打印效果一样好。

Important: iOS does not support device-independent or generic color spaces. iOS applications must use device color spaces instead.

重要提示:iOS不支持与设备无关或通用的颜色空间。 iOS应用程序必须使用设备颜色空间。

(1).Creating Device-Independent Color Spaces

To create a device-independent color space, you provide Quartz with the reference white point, reference black point, and gamma values for a particular device. Quartz uses this information to convert colors from your source color space into the color space of the output device.

要创建与设备无关的颜色空间,您可以向Quartz提供特定设备的参考白点,参考黑点和伽玛值。 Quartz使用此信息将颜色从源颜色空间转换为输出设备的颜色空间。

The device-independent color spaces supported by Quartz, and the functions that create them are:

  • Lab* is a nonlinear transformation of the Munsell color notation system (a system that specifies colors by hue, value, and saturation—or chroma —values). This color space matches perceived color difference with quantitative distance in color space. The L* component represents the lightness value, the a* component represents values from green to red, and the b* component represents values from blue to yellow. This color space is designed to mimic how the human brain decodes color. Use the functionCGColorSpaceCreateLab.
  • ICC is a color space from an ICC color profile, as defined by the International Color Consortium. ICC profiles define the gamut of colors supported by a device along with other device characteristics so that this information can be used to accurately transform the color space of one device to the color space of another. The manufacturer of the device typically provides an ICC profile. Some color monitors and printers contain embedded ICC profile information, as do some bitmap formats such as TIFF. Use the function CGColorSpaceCreateICCBased.
  • Calibrated RGB is a device-independent RGB color space that represents colors relative to a reference white point that is based on the whitest light that can be generated by the output device. Use the function CGColorSpaceCreateCalibratedRGB.
  • Calibrated gray is a device-independent grayscale color space that represents colors relative to a reference white point that is based on the whitest light that can be generated by the output device. Use the function CGColorSpaceCreateCalibratedGray.

Quartz支持的与设备无关的颜色空间以及创建它们的功能有:

  • Lab是孟塞尔彩色符号系统的非线性变换(通过色调,值和饱和度或色度值指定颜色的系统)。 这个颜色空间将感知色差与色彩空间中的定量距离相匹配。 L分量表示亮度值,a分量表示从绿色到红色的值,b分量表示从蓝色到黄色的值。 这个色彩空间被设计为模仿人类大脑如何解码颜色。 使用函数CGColorSpaceCreateLab。
  • ICC是由国际色彩联盟定义的ICC颜色配置文件的颜色空间。 ICC配置文件定义了设备支持的颜色以及其他设备特性,使得该信息可以用于将一个设备的颜色空间精确地转换为另一个设备的颜色空间。该设备的制造商通常提供ICC配置文件。一些彩色显示器和打印机包含嵌入式ICC配置文件信息,一些位图格式(如TIFF)也是如此。使用函数CGColorSpaceCreateICCBased。
  • 标准的RGB是与设备无关的RGB颜色空间,其表示相对于参考白点的颜色,其基于可由输出设备生成的最亮的光。使用函数CGColorSpaceCreateCalibratedRGB。
  • 标准的灰色是与设备无关的灰度色彩空间,其表示相对于基于可由输出设备生成的最亮光的参考白点的颜色。使用函数CGColorSpaceCreateCalibratedGray。
(2).Creating Generic Color Spaces(通用颜色空间)

Generic color spaces leave color matching to the system. For most cases, the result is acceptable. Although the name may imply otherwise, each “generic” color space—generic gray, generic RGB, and generic CMYK—is a specific device-independent color space.

通用颜色空间的颜色与系统匹配。 在大多数情况下,结果是可以接受的。 就像名字暗示的,每个“通用”颜色空间 - 通用灰色,通用RGB和通用CMYK是特定的设备无关色彩空间。

Generic color spaces are easy to use; you don’t need to supply any reference point information. You create a generic color space by using the function CGColorSpaceCreateWithName along with one of the following constants:

  • kCGColorSpaceGenericGray, which specifies generic gray, a monochromatic color space that permits the specification of a single value ranging from absolute black (value 0.0) to absolute white (value 1.0).
  • kCGColorSpaceGenericRGB, which specifies generic RGB, a three-component color space (red, green, and blue) that models the way an individual pixel is composed on a color monitor. Each component of the RGB color space ranges in value from 0.0 (zero intensity) to 1.0 (full intensity).
  • kCGColorSpaceGenericCMYK, which specifies generic CMYK, a four-component color space (cyan, magenta, yellow, and black) that models the way ink builds up during printing. Each component of the CMYK color space ranges in value from 0.0 (does not absorb the color) to 1.0 (fully absorbs the color).

通用色彩空间易于使用; 您不需要提供任何参考点信息。 通过使用函数CGColorSpaceCreateWithName以及以下常量之一创建通用颜色空间:

  • kCGColorSpaceGenericGray,其指定通用灰色,允许指定从绝对黑色(值0.0)到绝对白色(值1.0)的单个值的单色颜色空间。
  • kCGColorSpaceGenericRGB,其指定通用RGB,三分量颜色空间(红色,绿色和蓝色),其模拟在彩色监视器上组成单个像素的方式。 RGB颜色空间的每个分量的值从0.0(零强度)到1.0(全强度)。
  • kCGColorSpaceGenericCMYK,其指定通用CMYK,四分量颜色空间(青色,品红色,黄色和黑色),用于模拟打印期间墨水的构建方式。 CMYK颜色空间的每个组成部分的值从0.0(不吸收颜色)到1.0(完全吸收颜色)。
(3).Creating Device Color Spaces(创建设备依赖颜色空间)

Device color spaces are primarily used by iOS applications because other options are not available. In most cases, a Mac OS X application should use a generic color space instead of creating a device color space. However, some Quartz routines expect images with a device color space. For example, if you call CGImageCreateWithMask and specify an image as the mask, the image must be defined with the device gray color space.

设备颜色空间主要由iOS应用程序使用,因为其他选项不可用。 在大多数情况下,Mac OS X应用程序应使用通用颜色空间,而不是创建设备颜色空间。 然而,一些Quartz例程期望具有设备颜色空间的图像。 例如,如果您调用CGImageCreateWithMask并指定图像作为遮照,则图像必须使用设备灰色的颜色空间进行定义。

You create a device color space by using one of the following functions:

  • CGColorSpaceCreateDeviceGray for a device-dependent grayscale color space.
  • CGColorSpaceCreateDeviceRGB for a device-dependent RGB color space.
  • CGColorSpaceCreateDeviceCMYK for a device-dependent CMYK color space.

你可以使用以下函数创建设备颜色空间:

  • CGColorSpaceCreateDeviceGray:创建设备依赖灰度颜色空间。
  • CGColorSpaceCreateDeviceRGB:创建设备依赖RGB颜色空间。
  • CGColorSpaceCreateDeviceCMYK:创建设备依赖CMYK颜色空间。
(4).Creating Indexed and Pattern Color Spaces(创建索引和模式颜色空间)

Indexed color spaces contain a color table with up to 256 entries, and a base color space to which the color table entries are mapped. Each entry in the color table specifies one color in the base color space. Use the function CGColorSpaceCreateIndexed.

索引的颜色空间包含最多256个条目的颜色表,以及颜色表条目映射到的基色空间。 颜色表中的每个条目指定基色空间中的一种颜色。 使用函数CGColorSpaceCreateIndexed。

Pattern color spaces, discussed in Patterns, are used when painting with patterns. Use the function CGColorSpaceCreatePattern.

模式中讨论的图案颜色空间在使用图案绘制时使用。 使用函数CGColorSpaceCreatePattern。

4.Setting and Creating Colors(设置和创建颜色)

Quartz provides a suite of functions for setting fill color, stroke color, color spaces, and alpha. Each of these color parameters apply to the graphics state, which means that once set, that setting remains in effect until set to another value.

Quartz提供了一套用于设置填充颜色,笔画颜色,颜色空间和alpha的功能。 这些颜色参数中的每一个都适用于图形状态,这意味着一旦设置,该设置将保持有效,直到设置为另一个值。

A color must have an associated color space. Otherwise, Quartz won’t know how to interpret color values. Further, you need to supply an appropriate color space for the drawing destination. Compare the blue fill color on the left side of Figure 4-4, which is a CMYK fill color, with the blue color shown on the right side, which is an RGB fill color. If you view the onscreen version of this document, you’ll see a large difference between the fill colors. The colors are theoretically identical, but appear identical only if the RGB color is used for an RGB device and the CMYK color is used for a CMYK device.

颜色必须具有相关联的颜色空间。 否则,Quartz将不知道如何解释颜色值。 此外,您需要为绘图目标提供适当的颜色空间。 比较图4-4左侧的蓝色填充颜色,该颜色是CMYK填充颜色,右侧显示蓝色,这是RGB填充颜色。 如果您查看该文档的屏幕版本,您将看到填充颜色之间有很大差异。 颜色在理论上是相同的,但只有RGB颜色用于RGB设备,并且CMYK颜色用于CMYK设备,才会出现相同的。

Figure 4-4  A CMYK fill color and an RGB fill color
Figure 4-4 A CMYK fill color and an RGB fill color

You can use the functions CGContextSetFillColorSpace and CGContextSetStrokeColorSpace to set the fill and stroke color spaces, or you can use one of the convenience functions (listed in Table 4-2) that set color for a device color space.

您可以使用函数CGContextSetFillColorSpace和CGContextSetStrokeColorSpace来设置填充和描边颜色空间,也可以使用为设备颜色空间设置颜色的方便功能(表4-2中列出)。

Table 4-2 Color-setting functions

Function Use to set color for
CGContextSetRGBStrokeColor CGContextSetRGBFillColor Device RGB. At PDF-generation time, Quartz writes the colors as if they were in the corresponding generic color space.
CGContextSetCMYKStrokeColor CGContextSetCMYKFillColor Device CMYK. (Remains device CMYK at PDF-generation time.)
CGContextSetGrayStrokeColor CGContextSetGrayFillColor Device Gray. At PDF-generation time, Quartz writes the colors as if they were in the corresponding generic color space.
CGContextSetStrokeColorWithColor CGContextSetFillColorWithColor Any color space; you supply a CGColor object that specifies the color space. Use these functions for colors you need repeatedly.
CGContextSetStrokeColor CGContextSetFillColor The current color space. Not recommended. Instead, set color using a CGColor object and the functions CGContextSetStrokeColorWithColor and CGContextSetFillColorWithColor.

You specify the fill and stroke colors as values located within the fill and stroke color spaces. For example, a fully saturated red color in the RGB color space is specified as an array of four numbers: (1.0, 0.0, 0.0, 1.0). The first three numbers specify full red intensity and no green or blue intensity. The fourth number is the alpha value, which is used to specify the opacity of the color.

您可以将填充和笔触颜色指定为填充和笔触颜色空间中的值。 例如,RGB颜色空间中的完全饱和红色指定为四个数字的数组:(1.0,0.0,0.0,1.0)。 前三个数字指定全红色强度,无绿色或蓝色强度。 第四个数字是alpha值,用于指定颜色的不透明度。

If you reuse colors in your application, the most efficient way to set fill and stroke colors is to create a CGColor object, which you then pass as a parameter to the functions CGContextSetFillColorWithColor and CGContextSetStrokeColorWithColor. You can keep the CGColor object around as long as you need it. You can improve your application’s performance by using CGColor objects directly.

如果您在应用程序中重用颜色,则设置填充和描边颜色最有效的方式是创建一个CGColor对象,然后将其作为参数传递给函数CGContextSetFillColorWithColor和CGContextSetStrokeColorWithColor。 我们可以按需要保持CGColor对象, 并可以直接使用CGColor对象来提高应用程序的性能。

You create a CGColor object by calling the function CGColorCreate, passing a CGColorspace object and an array of floating-point values that specify the intensity values for the color. The last component in the array specifies the alpha value.

您可以通过调用CGColorCreate函数创建一个CGColor对象,传递一个CGColorspace对象和一个指定颜色强度值的浮点值数组。数组中的最后一个组件指定alpha值。

5.Setting Rendering Intent(设置渲染目标)

The rendering intent specifies how Quartz maps colors from the source color space to those that are within the gamut of the destination color space of a graphics context. If you don’t explicitly set the rendering intent, Quartz uses relative colorimetric rendering intent for all drawing except bitmap (sampled) images. Quartz uses perceptual rendering intent for those.

渲染意图指定了Quartz如何将源颜色空间的颜色映射到图形上下文的目标色彩空间范围内的颜色。 如果没有显式设置渲染意图,Quartz对于除位图(采样)图像之外的所有绘图使用相对比色渲染意图。 Quartz使用感知渲染意图。

To set the rendering intent, call the function CGContextSetRenderingIntent, passing a graphics context and one of the following constants:

  • kCGRenderingIntentDefault. Uses the default rendering intent for the context.
  • kCGRenderingIntentAbsoluteColorimetric. Maps colors outside of the gamut of the output device to the closest possible match inside the gamut of the output device. This can produce a clipping effect, where two different color values in the gamut of the graphics context are mapped to the same color value in the output device’s gamut. This is the best choice when the colors used in the graphics are within the gamut of both the source and the destination, as is often the case with logos or when spot colors are used.
  • kCGRenderingIntentRelativeColorimetric. The relative colorimetric shifts all colors (including those within the gamut) to account for the difference between the white point of the graphics context and the white point of the output device.
  • kCGRenderingIntentPerceptual. Preserves the visual relationship between colors by compressing the gamut of the graphics context to fit inside the gamut of the output device. Perceptual intent is good for photographs and other complex, detailed images.
  • kCGRenderingIntentSaturation. Preserves the relative saturation value of the colors when converting into the gamut of the output device. The result is an image with bright, saturated colors. Saturation intent is good for reproducing images with low detail, such as presentation charts and graphs.

要设置渲染意图,调用函数CGContextSetRenderingIntent,传递图形上下文和以下常量之一:

  • kCGRenderingIntentDefault:使用默认方式渲染意图。
  • kCGRenderingIntentAbsoluteColorimetric(绝对色度渲染意图):将输出设备的色域外的颜色映射到输出设备的色域内最接近的可能匹配。 这可以产生剪辑效果,其中图形上下文的色域中的两个不同颜色值被映射到输出设备的色域中的相同颜色值。 当图形中使用的颜色在源和目的地的色域内时,通常在使用徽标或使用专色时这是最好的选择。
  • kCGRenderingIntentRelativeColorimetric(相对色度渲染意图):相对比色会移动所有颜色(包括色域内的颜色),以考虑图形上下文的白点与输出设备的白点之间的差异。
  • kCGRenderingIntentPerceptual(感知渲染意图):通过压缩图形上下文的色域以保持输出设备的色域内,保持颜色之间的视觉关系。感知意图适用于照片和其他复杂,详细的图像。
  • kCGRenderingIntentSaturation(饱和度渲染意图):当转换为输出设备的色域时,保留颜色的相对饱和度值。结果是具有明亮,饱和的颜色的图像。饱和意图对于再现具有低细节的图像(如演示图表和图形)很有用。

推荐阅读更多精彩内容