颜色与色域 —— Quartz 2D编程指导翻译 第5篇

本文翻译自苹果官方文档:原文地址

颜色与色域

不同设备(显示器、打印机、扫描仪、照相机)对颜色的表现并不是相同的,每个设备都拥有它自己能够产生的的颜色范围。在某个设备上能够显示的颜色未必能够在另一不同设备上显示。

想要有效的与颜色打交道或者想要明白Quartz 2D中使用颜色和色域的函数,你应当熟悉一下颜色管理综述。该文档讨论了颜色的概念、色值、设备独立和设备色域、颜色匹配问题、渲染意图、颜色管理模块、以及颜色同步(ColorSync)。

在本章中,你会学习到Quartz如何表示颜色和色域、alpha是啥。本章也讨论:

  • 创建色域
  • 创建和设置颜色
  • 设置渲染意图

关于颜色和色域

Quartz用一系列的值代表一个颜色。这些值离开了色域是毫无意义的;色域描述了如何解释颜色信息。表4-1均表示纯强度下的蓝色;如果不知道色域和每个色域允许的范围值,我们就没有办法知道这些值代表什么颜色。

表4-1

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

图4-1所示,如果提供了错误的色域,那么可能得到相当戏剧性的结果。虽然在BGRRGB中绿色的位置相同,但是红色和蓝色的的位置却相反。

图4-1 对同一张图片使用BGR和RGB色域

图4-1 对同一张图片使用BGR和RGB色域

不同色域可以拥有不同的分量值,正如表4-1所示,其中的三个色域拥有三个分量,而CMYK拥有4个分量;与此同时其分量的取值范围也和色域相关。Quartz中大多数的色域取值范围在0.0~1.0之间;1.0意味着全强度。例如Quartz中全强度的蓝色在RGB色域下的值为:(0.0, 0.0, 1.0)。同时,Quartz中颜色拥有一个alpha值,该值表示其透明度,表4-1中没有展示alpha值。

Alpha值

AlphaQuartz用来决定如何向已经存在的页上绘制新的物体,它是一个图形状态参数(graphics state)图4-2展示了用1.0、0.75、0.5、0.1和0.0这5个alpha值绘制一个大矩形到一个不透明的小矩形上。

图4-2一系列透明度的绘制

图4-2一系列透明度的绘制

你可以在绘制前,设置全局图形上下文alpha参数来同时改变页和页上物体的透明度。图4-3展示了全局设置为0.5和默认的1.0绘制的区别。

图4-3全局alpha参数对比

图4-3全局alpha参数对比

在普通混色模式中(默认的图形状态)Quartz通过如下的公式结合源颜色分量和目的颜色分量达到透明度混合。

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

其中源是指将要绘制新颜色的一个分量目的是指背景色的一个分量;这个公式在每次绘制新图形或者图片时都会执行。

对于物体的透明度来说设置成1.0表示完全不透明,设置成0.0表示完全透明,在0.0~1.0之间的值则表示半透明。你可以为接受颜色的操作指定alpha值为颜色的最后一个分量;也可以通过函数CGContextSetAlpha来设置全局alpha值。如果你设置了两个值,那么在计算的时候Quartz会将他们相乘。

当图形上下文是一个窗口或者bitmap时,如果你想允许这个页自身完全透明,可以显示的调用CGContextClearRect,来清除图形上下文中的alpha通道。在你想为一个图标做遮罩或想让窗口的背景透明时可能会用到这种操作。

创建色域

Quartz不仅支持标准色域(被颜色管理系统用于设备独立的色域),还支持通用、索引、样章色域。设备独立的色域使用了一种可以移植的表示方法来表达颜色,它被用于从一个设备上的原生颜色到另一个设备上的原生颜色的转换。设备独立色域中的颜色,在不同的设备上表现是一致的(设备允许的误差范围内),因此设备独立色域是我们表示颜色最好的选择。

对于有精确颜色要求的应用来说,应当使用设备独立的色域。自定义的设备独立色域是通用颜色色域。 通用色域会让操作系统为应用提供最适合的颜色空间(色域);在显示器上绘制的效果就像打印一样。

注: iOS不支持设备独立色域和通用色域。iOS应用必须使用设备相关色域(device color spaces)。

创建设备独立色域

要创建设备独立色域,需要向Quartz提供参考白点参考黑点以及特定设备的伽马值(gamma values)Quartz使用这些信息将颜色从源色域转换到输出设备的色域。

Quartz支持设备独立色域,创建的函数是:

  • L*a*b* 是一个非线性的孟塞尔颜色标记系统(一个使用色调、值、和饱和度来表示颜色的系统)的转换。这种色域空间使得颜色的差异与色域中的量化距离相匹配。L*分量亮度,a*分量表示从绿色到红色的值,b*分量表示从蓝色到黄色的值。该色域在设计时效仿了人脑解读颜色的过程。使用函数CGColorSpaceCreateLab创建。
  • ICC是由国际颜色联合定义在ICC颜色描述文件中的色域。ICC描述文件中定义了一个设备与另一个特殊的设备能够支持的颜色总量,其目的是这个信息能够被用于从一个设备的色域准确的转换到另一个设备的色域。设备的制造者通常会提供一个ICC描述文件;有些显示器和打印机甚至内嵌了ICC描述文件,一些位图格式(如TIFF)也是如此。使用函数CGColorSpaceCreateICCBased创建。
  • 校准RGB是一个设备独立的RGB色域,它表示相对于参考白点的颜色,参考白点是基于输出设备所能产生的最白光。使用函数CGColorSpaceCreateCalibratedRGB创建。
  • 校准的灰是一个设备独立的灰度色域,这个色域表示相对于参考白点的颜色,参考白点是基于输出设备所能产生的最白光。使用函数CGColorSpaceCreateCalibratedGray创建。
创建通用色域

通用色域将颜色匹配交给了系统,大多数情况下,结果是能够接受的。虽然通用这个名字有所暗示,但是每个带有“通用”的色域:通用灰、通用RGB、通用CMYK都是具体的设备独立色域。

通用色域使用时很简单,不需要提供任何参考点;可以通过函数CGColorSpaceCreateWithName传入如下的常量来创建通用色域:

  • kCGColorSpaceGenericGray,表示通用灰,它是一个单调的色域,使用一个简单的值来描述纯黑(0.0)到纯白(1.0)。
  • kCGColorSpaceGenericRGB,表示通用RGB,由三个分量组成(red, green, blue),其模拟了显示器独立的像素组成,每个分量都由0.0(零强度)~1.0(满强度)。
  • kCGColorSpaceGenericCMYK,表示通用CMYK,由4个分量组成(cyan, magenta, yellow, black),其模拟了打印时幽默的生成,每个分量从0.0(不溶解颜色)~1.0(完全溶解颜色)。
创建设备相关颜色

设备相关色域主要用于iOS应用程序,因为其他选择是不可用的。在大多数情况下,Mac OS X 应用应当使用通用色域而不是设备相关色域;但是有些Quartz操作需要用到设备相关色域,例如使用CGImageCreateWithMask指定一个图片为遮罩时,图片必须被定义在设备相关灰色域中。

使用如下函数创建设备相关色域:

  • CGColorSpaceCreateDeviceGray,创建设备相关的灰度色域。
  • CGColorSpaceCreateDeviceRGB,创建设备相关的RGB色域。
  • CGColorSpaceCreateDeviceCMYK,创建设备相关的CMYK色域。
创建索引和样章色域

索引色域包含一个至多含有256个实体的颜色表和一个与各个实体映射的基础色域;每一个实体在该色域中代表一种颜色。使用CGColorSpaceCreateIndexed创建。

样章色域主要在Patterns中讨论;通常在我们使用样章的时候会用到,函数CGColorSpaceCreatePattern可以创建这种色域。

设置和创建颜色

Quartz提供了一系列的方法来设置填充色、描边色、色域以及alpha。对每个参数的设置都会保存到图形状态中,这也就意味着,你在设置一个值之后会一直有效(除非你新设置另一个值)。

颜色必须和色域关联,否则Quartz不知道怎么去解析颜色;为要绘制的目的也要提恰当的色域。比较图4-4中蓝色填充色的差别,左边是CMYK下的填充色,右边是RGB下的填充色,如果你使用的是显示器查看这个图片,那么你能看到很大的差别。这两个颜色从理论上来说是相同的,只有当CMYK色域下的图片显示到CMYK设备且RGB色域下的图片显示到RGB设备时才会看起来一样。

图4-4 CMYK填充色和RGB填充色

图4-4 CMYK填充色和RGB填充色

你可以使用CGContextSetFillColorSpaceCGContextSetStrokeColorSpace来设置填充和描边的色域;你也可以使用下表(4-2)中的函数来方便的设置一个设备相关色域中的颜色。

表4-2 颜色设置函数

函数 色域与描述
CGContextSetRGBStrokeColor
CGContextSetRGBFillColor
设备相关RGB色域;在PDF生成时Quartz取相应的通用色域中的颜色来绘制。
CGContextSetCMYKStrokeColor
CGContextSetCMYKFillColor
设备相关RGB色域;在PDF生成时保留这个色域。
CGContextSetGrayStrokeColor
CGContextSetGrayFillColor
设备相关的灰色域;在PDF生成时Quartz取相应的通用色域中的颜色来绘制。
CGContextSetStrokeColorWithColor
CGContextSetFillColorWithColor
任意色域;需要提供一个包含色域信息的CGColor对象,通常在需要重复使用某一颜色时使用。
CGContextSetStrokeColor
CGContextSetFillColor
当前色域,不推荐。建议使用CGContextSetStrokeColorWithColorCGContextSetFillColorWithColor

指定描边和填充颜色时,就像是取相应色域中的某个值。例如,一个完全浸透的红色在RGB色域下由一个含有4个数字的数组构成:(1.0, 0.0, 0.0, 1.0);前三个分量表示全强度的红以及没有绿和蓝,第四个参数是alpha值,它用来表示这个颜色的透明度。

如果应用中复用颜色,通常利用CGColor对象来设置填充色和秒变色,相关的函数是:CGContextSetFillColorWithColorCGContextSetStrokeColorWithColor。使用这种方法能够保留CGColor对象到适当的时候;直接使用CGColor能够提高性能。

通过调用函数CGColorCreate传入适当的色域参数和浮点的数组分量值来创建指定的颜色;浮点数组中最后一个分量是alpha值。

设置渲染意图

渲染意图指明了Quartz如何从源色域映射到一个图形上下文的目的色域范围。如果没指明渲染意图,Quartz为所有了绘制(位图图片除外)使用相关的比色渲染意图;对于位图图片则使用感知渲染意图。

调用CGContextSetRenderingIntent函数并传入如下的常量之一来设置渲染意图:

  • kCGRenderingIntentDefault,对图形上下文使用默认的渲染意图。
  • kCGRenderingIntentAbsoluteColorimetric,将输出设备的色域外的颜色映射到输出设备的色域内最匹配的颜色。当图形上下文色域中的两个不同颜色值映射到输出设备色域中为相同的颜色时,会产生剪切效果。当图形中使用的颜色在源和目标的色域内时,这是最好的选择;通常用于logo和点色使用。
  • kCGRenderingIntentRelativeColorimetric,相对比色改变了所有的颜色(包括色域范围内的颜色),这么做是为了协调图形上下文和输出设备的白点值。
  • kCGRenderingIntentPerceptual,通过压缩图形上下文的色域以适应输出设备的色域,保持了颜色之间的视觉关系;对于照片和其他复杂、游戏界的图像是有好处的。
  • kCGRenderingIntentSaturation,当转换成输出设备的色域时,保留颜色的相对饱和度值;使图像具有明亮、饱和的颜色;该意图有利于展示低细节的图像,如表示图表和图形。

上一章:路径(Paths)
下一章:Transforms(暂未翻译)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容