不同的设备(显示器、打印机、扫描仪、摄像头)处理颜色的方式是不同的。每种设备都有其所能支持的颜色值范围。一种设备能支持的颜色可能在其它设备中无法支持。
为了有效的使用颜色及理解Quartz 2D中用于颜色及颜色空间的函数,我们需要熟悉在Color Management Overview文档中所使用的术语。该文档中讨论了色觉、颜色值、设备依赖及设备颜色空间、颜色匹配问题、再现意图(rendering intent)、颜色管理模块和ColorSync。
在本章中,我们将学习Quartz处理颜色和颜色空间,以及什么是alpha组件。本章同时也讨论如下问题:

  • 创建颜色空间
  • 创建和设置颜色
  • 设置再现意图

颜色与颜色空间
Quartz中的颜色是用一组值来表示。而颜色空间用于解析这些颜色信息。例如,表4-1列出了在全亮度下蓝色值在不同颜色空间下的值。如果不知道颜色空间及颜色空间所能接受的值,我们没有办法知道一组值所表示的颜色。

如果我们使用了错误的颜色空间,我们可能会获得完全不同的颜色,如图4-1所示。

颜色空间可以有不同数量的组件。表4-1中的颜色空间中其中三个只有三个组件,而CMYK有四个组件。值的范围与颜色空间有关。对大部分颜色空间来说,颜色值范围为[0.0, 1.0],1.0表示全亮度。例如,全亮度蓝色值在Quartz的RGB颜色空间中的值是(0, 0, 1.0)。在Quartz中,颜色值同样有一个alpha值来表示透明度。在表4-1中没有列出该值。
alpha值
alpha值是图形状态参数,Quartz用它来确定新的绘图对象如何与已存在的对象混合。在全强度下,新的绘图对象是不透明的。在0强度下,新的绘图对象是完全透明的。图4-2显示了5个大的方形,分别使用了alpha值为1.0, 0.75, 0.5, 0.1和0.0。随着大方形逐渐变得透明,底下的小的不透明的方形逐渐显现出来。

我们可以将两个对象绘制到page上,而page可以在渲染前通过设置全局的graphics context来设置自己的透明度。图4-3显示了将全局的透明度设置为0.5和1.0的效果。

在标准混合模式(图形状态的默认模式)下,Quartz使用下面的公式来混合源颜色和目标颜色的组件:

 

复制代码

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

其中源颜色是新绘制的颜色,目标颜色是背景颜色。该公式可用于新绘制的形状和图像。
对于对象透明度来说,alpha值为1.0时表示新对象是完全不透明的,值0.0表示新对象是完全透明的。0.0与1.0之间的值指定对象的透明度。我们可以为所有接受颜色的程序指定一个alpha值作为颜色值的最后一个组件。同样也可以使用CGContextSetAlpha函数来指定全局的alpha值。记住,如果同时设置以上两个值,Quartz将混合全局alpha值与对象的alpha值。
为了让page完全透明,我们可以调用CGContextClearRect函数来清除图形上下文(graphics context)的alpha通道。例如,我们可以在给图标创建一个透明遮罩或者使窗口的背景透明时,采用这种方法。
创建颜色空间
Quartz支持颜色管理系统使用的标准颜色空间,也支持通用的颜色空间、索引颜色空间和模式(pattern)颜色空间。设备颜色空间以一种简便的方法在不同设备间表示颜色。它用于在两种不同设备间的本地颜色空间转换颜色数据。设备依赖颜色空间的颜色在不同设备上显示时效果是一样的,它扩展了设备的能力。基于此,设备依赖颜色空间是显示颜色时最好的选择。
如果应用程序有精确的颜色表示需求,则应该总是使用设备依赖颜色空间。通用颜色空间(generic color space)是一种常用的设备依赖颜色空间。通用颜色空间通过操作系统为我们的应用程序提供最好的颜色空间。它能使在显示器上与在打印机上打印效果是一样的。

引用
text\">重要:IOS不支持设备依赖颜色空间或通用颜色空间。IOS应用程序必须使用设备颜色空间(device color space)。

创建设备依赖颜色空间
为了创建设备依赖颜色空间,我们需要给Quartz提供白色参考点,黑色参考点及特殊设备的gamma值。Quartz使用这些信息将源颜色空间的颜色值转化为输出设备颜色空间的颜色值。
Quartz支持设备依赖颜色空间,创建此空间的函数如下:

  • L*a*b是非线性转换,它属于Munsell颜色符号系统(该系统使用色度、值、饱和度来指定颜色)。 L组件表示亮度值,a组件表示绿色与红色之间的值,b组件表示蓝色与黄色之间的值。该颜色空间设计用于模拟人脑解码颜色。使用函数CGColorSpaceCreateLab来创建。
  • ICC颜色空间是由ICC(由国际色彩聪明,International Color Consortium)颜色配置而来的。ICC颜色配置了设备支持的颜色域,该颜色域与其它设备属性相符,所以该信息可被用于将一个设备的颜色空间精确地转换为另一个设备的颜色空间。大多数设备制造商都支持ICC配置。一些彩色显示器和打印机都内嵌了ICC信息,用于处理诸如TIFF的位图格式。使用函数CGColorSpaceCreateICCBased来创建。
  • 标准化RGB是设备依赖的RGB颜色空间,它表示相对于白色参考点(设备可生成的最白的颜色)的颜色。 使用函数CGColorSpaceCreateCalibratedRGB来创建。
  • 标准化灰度是设备依赖的灰度颜色空间,它表示相对于白色参考点(设备可生成的最白的颜色)的颜色。 使用函数CGColorSpaceCreateCalibratedGray来创建。

创建通用颜色空间
通用颜色空间的颜色与系统匹配。大部分情况下,结果是可接受的。就像名字所暗示的那样,每个“通用”颜色空间(generic gray, generic RGB, generic CMYK)都是一个指定的设备依赖颜色空间。
通过颜色空间非常容易使用;我们不需要提供任何参考点信息。我们使用函数CGColorSpaceCreateWithName来创建一个通用颜色空间,该函数可传入以下常量值:

  • kCGColorSpaceGenericGray:指定通用灰度颜色空间,该颜色空间是单色的,可以指定从0.0(纯黑)到1.0(纯白)范围内的颜色值。
  • kCGColorSpaceGenericRGB:指定通用RGB颜色空间,该颜色空间中的颜色值由三个组件(red, green, blue)组成,主要用于彩色显示器上的像素。RGB颜色空间中的每个组件的值范围是[0.0, 1.0]。
  • kCGColorSpaceGenericCMYK:指定通用CMYK颜色空间,该颜色空间的颜色值由四个组件(cyan, magenta, yellow, black),主要用于打印机。CMYK颜色空间的每个组件的值范围是[0.0, 1.0]。

创建设备颜色空间
设备颜色空间主要用于IOS应用程序,因为其它颜色空间无法在IOS上使用。大多数情况下,Mac OS X应用程序应使用通用颜色空间,而不使用设备颜色空间。但是有些Quartz程序希望图像使用设备颜色空间。例如,如果调用CGImageCreateWithMask函数来指定一个图像作为遮罩,图像必须在设备的灰度颜色空间(device gray color space)中定义。
我们可以使用以下函数来创建设备颜色空间:

  • CGColorSpaceCreateDeviceGray:创建设备依赖灰度颜色空间
  • CGColorSpaceCreateDeviceRGB:创建设备依赖RGB颜色空间
  • CGColorSpaceCreateDeviceCMYK:创建设备依赖CMYK颜色空间

创建索引颜色空间和模式颜色空间
索引颜色空间包含一个有256个词目的颜色表,和词目映射到基础颜色空间。颜色表中每个词目指定一个基础颜色空间中的颜色值。使用CGColorSpaceCreateIndexed函数来创建。
模式颜色空间在绘制模式时使用。 使用CGColorSpaceCreatePattern函数来创建。
设置和创建颜色
Quartz提供了一套函数用于设置填充颜色、线框颜色、颜色空间和alpha值。每个颜色参数都是图形状态参数,这就意味着一旦设置了,设置将被保存并影响后续操作,直到被修改为止。
一个颜色必须有相关联的颜色空间。否则,Quartz不知道如何解析颜色值。进一步说,说是我们必须为绘制目标提供一个合适的颜色空间。如图4-4所示,左边是CMYK颜色空间中的蓝色填充色,右边是RGB颜色空间中的蓝色填充色。这两个颜色值在理论上是一样的,但只有在相同颜色空间下的相同颜色值显示出来才是一样的。

我们可以使用CGContextSetFillColorSpace和CGContextSetStrokeColorSpace函数来设置填充和线框颜色空间,或者可以使用以下便利函数来设置设备颜色空间的颜色值。
Table 4-2  Color-setting functions

函数 用途
CGContextSetRGBStrokeColor
CGContextSetRGBFillColor
设备RGB。在生成PDF时,Quartz像在相应的通用颜色空间中一样写入颜色。
CGContextSetCMYKStrokeColor
CGContextSetCMYKFillColor
设备CMYK。在生成PDF时,保持设备CMYK
CGContextSetGrayStrokeColor
CGContextSetGrayFillColor
设备灰度。在生成PDF时,Quartz像在相应的通用颜色空间中一样写入颜色。
CGContextSetStrokeColorWithColor
CGContextSetFillColorWithColor
任何颜色空间;提供一个指定颜色空间的CGColor对象。
CGContextSetStrokeColor
CGContextSetFillColor
当前颜色空间。不推荐使用。更多时候我们使用CGColor对象和函数CGContextSetStrokeColorWithColor和CGContextSetFillColorWithColor。

我们在填充及线框颜色空间中指定填充及线框颜色值。例如,在RGB颜色空间中,我们使用数组(1.0, 0.0, 0.0, 1.0)来表示红色。前三个值指定红色值为全强度,而绿色和蓝色为零强度。第四个值为alpha值,用于指定颜色的透明度。
如果需要在程序中重复使用颜色,最有效的方法是通过设置填充色和线框色来创建一个CGColor对象,然后将该对象传递给函数CGContextSetFillColorWithColor及CGContextSetStrokeColorWithColor。我们可以按需要保持CGColor对象,并可以直接使用该对象来改进应用程序的显示。
我们可以调用CGColorCreate函数来创建CGColor对象,该函数需要两个参数:CGColorspace对象及颜色值数组。数组的最后一个值指定alpha值。
设置再现意图(Rending Intent)
“再现意图”用于指定如何将源颜色空间的颜色映射到图形上下文的目标颜色空间的颜色范围内。如果不显示指定再现意图,Quartz使用相对色度再现意图(relative colorimetric rendering intent)应用于所有绘制(不包含位图图像)。对于位图图像,Quartz默认使用感知(perceptual)再现意图。
我们可以调用CGContextSetRenderingIntent函数来设置再现意图,并传递图形上下文(graphics context)及下例常量作为参数:

  • kCGRenderingIntentDefault:使用默认的渲染意图。
  • kCGRenderingIntentAbsoluteColorimetric:绝对色度渲染意图。将输出设备颜色域外的颜色映射为输出设备域内与之最接近的颜色。这可以产生一个裁减效果,因为色域外的两个不同的颜色值可能被映射为色域内的同一个颜色值。当图形使用的颜色值同时包含在源色域及目标色域内时,这种方法是最好的。常用于logo或者使用专色(spot color)时。
  • kCGRenderingIntentRelativeColorimetric:相对色度渲染意图。转换所有的颜色(包括色域内的),以补偿图形上下文的白点与输出设备白点之间的色差。kCGRenderingIntentPerceptual:感知渲染意图。通过压缩图形上下文的色域来适应输出设备的色域,并保持源颜色空间的颜色之间的相对性。感知渲染意图适用于相片及其它复杂的高细度图片。
  • kCGRenderingIntentSaturation:饱和度渲染意图。把颜色转换到输出设备色域内时,保持颜色的相对饱和度。结果是包含亮度、饱和度颜色的图片。饱和度意图适用于生成低细度的图片,如描述性图表。

原帖地址:http://www.cocoachina.com/bbs/read.php?tid=78374

Quartz 2D编程指南(4) - 颜色和颜色空间的更多相关文章

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

    Quartz 2D编程指南是论坛会员德鲁伊翻译的国外的Quartz 2D一系列学习资料,供大家参考 Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境.我们可以使用Quar ...

  2. Quartz 2D编程指南(7) - 阴影(Shadows)

    阴影是绘制在一个图形对象下的且有一定偏移的图片,它用于模拟光源照射到图形对象上所形成的阴影效果,如果7-1所示.文本也可以有阴影.阴影可以让一幅图像看上去是立体的或者是浮动的. 阴影有三个属性: 1. ...

  3. Quartz 2D编程指南(2) - 图形上下文

    一个Graphics Context表示一个绘制目标.它包含绘制系统用于完成绘制指令的绘制参数和设备相关信息.Graphics Context定义了基本的绘制属性,如颜色.裁减区域.线条宽度和样式信息 ...

  4. Quartz 2D编程指南(2)图形上下文(Graphics Contexts)

    Graphics Contexts       一个Graphics Context表示一个绘制目标(也能够理解为图形上下文).它包括绘制系统用于完毕绘制指令的绘制參数和设备相关信息.Graphics ...

  5. Quartz 2D编程指南(5) - 变换(Transforms)

    Quartz 2D 绘制模型定义了两种独立的坐标空间:用户空间(用于表现文档页)和设备空间(用于表现设备的本地分辨率).用户坐标空间用浮点数表示坐标,与设备空间的像素分辨率没有关系.当我们需要一个点或 ...

  6. Quartz 2D编程指南- PDF文档的创建、显示及转换

    PDF文档存储依赖于分辨率的向量图形.文本和位图,并用于程序的一系列指令中.一个PDF文档可以包含多页的图形和文本.PDF可用于创建跨平台.只读的文档,也可用于绘制依赖于分辨率的图形.         ...

  7. Quartz 2D Programming Guide

    Quartz 2D Programming  Guide 官方文档: Quartz 2D Programming Guide 译文: Quartz 2D编程指南(1) - 概览 Quartz 2D编程 ...

  8. iPhone之Quartz 2D系列--编程指南(1)概览

    以下几遍关于Quartz 2D博文都是转载自:http://www.cocoachina.com/bbs/u.php?action=topic&uid=38018 iPhone之Quartz ...

  9. Quartz2D 编程指南(一)概览、图形上下文、路径、颜色与颜色空间

    概览 图形上下文 路径 颜色与颜色空间 变换 图案 阴影 渐变 透明层 Quartz 2D 中的数据管理 位图与图像遮罩 CoreGraphics 绘制 Layer 0.说明 本篇博客主要是对官方文档 ...

随机推荐

  1. codeforces600E Lomsat gelral

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  2. thinkphp getField("xxxxx", true); 得到一个字段所有值组成的的数组

    很多时候我们只需要一张表里某个字段的值,组成的数组 $Channel = D('channel');$channelList = $Channel->order('user_name')-> ...

  3. activiti如何让业务对象和对应的流程关联

    如何让业务对象和对应的流程 关联? 发现ProcessInstance 有个方法getBusinessKey()可以得到一个businessKey. ProcessInstance 对应数据库中的表a ...

  4. rdlc报表出现多余空白页面

    1.RDLC报表设计好后,在ReportViewer预览报表时,页数都正常:但在切换为整页模式时,常造成多了不少空白页出来.第一时间觉得不可思议,在ReportViewer看来正常,怎可能在整页预览时 ...

  5. cJONS序列化工具解读二(数据解析)

    cJSON数据解析 关于数据解析部分,其实这个解析就是个自动机,通过递归或者解析栈进行实现数据的解析 /* Utility to jump whitespace and cr/lf *///用于跳过a ...

  6. IOS UI-控制器的生命周期

    一.控制器的生命周期 代码 @interface NJOneViewController () @property (nonatomic, strong) NSArray *foods; @end @ ...

  7. day29 主机管理-堡垒机2-原生ssh会话记录

    day29课堂代码:https://github.com/liyongsan/git_class/tree/master/day29 课堂笔记: 通过原生Ssh 记录会话1. 在我们自己的堡垒机交互脚 ...

  8. LeetCode OJ:Search a 2D Matrix II(搜寻二维矩阵)

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  9. 【javascript基础】 JavaScript defer和async区别

    defer该属性用来通知浏览器,这段脚本代码将不会产生任何文档内容.例如 JavaScript代码中的document.write()方法将不会骑作用,浏览器遇到这样的代码将会忽略,并继续执行后面的代 ...

  10. diff和patch 打补丁

    在Linux环境下,有两个工具用来给project打补丁,即diff和patch diff         diff具有比较功能.可以使用man命令查看其使用方法. NAME        diff ...