关于色彩模型的最新成果

来源:互联网 发布:凤凰卫视网络停播 编辑:程序博客网 时间:2024/06/10 12:27

已经有一个多星期没有写开发日志了,不过这并不表示没有任何进展,相反,在这一周中,色彩模型已经经历了几次重大的变化。

首先,考虑下面几个基本的问题:

  1. 索引应当是一种存储格式,而不是颜色模式。
  2. 每个颜色数据还应带有一个 Alpha 值。
  3. 只有 Lab 颜色(甚至可以采用 32 位)是绝对的,其它的颜色都不能独立存在,而需要色彩管理文件。

下面来慢慢讨论:

之前混淆了颜色与像素的概念,导致一直将索引模式也作为颜色模式来考虑,后来才发现这完全错误了。Photoshop 的颜色模式只是它的工作模式,表示像素的存储方式,而真正的颜色模式并没有那么丰富——就算是索引模式,它最后还是需要指向具体的颜色信息。因此,索引模式只是使用索引方式来存储 RGB/8 颜色信息而已。这样一来,所有的颜色都将归结为“通道色”的概念,每个颜色由一个或多个通道组成,各通道采用相同的颜色位深度,具有各自的连续取值范围。

除了本身的通道之外,每个颜色数据还带有 Alpha 值。在存储上,Alpha 值与其它通道值(如 R、G、B)是完全平等的,有自己的取值范围,与其它通道使用相同的位深度。如果也将其视为一个通道,那么可以与其它通道使用相同的处理机制,看起来是一个很不错的选择。然而,很快这种想法就遇到了麻烦:事实上,当两个颜色进行混合时,Alpha 值和通道值并不平等:

R = R' * alpha + R * (1 - alpha)
G = G' * alpha + G * (1 - alpha)
B = B' * alpha + B * (1 - alpha)

也就是说,Alpha 值与其它颜色分量通道的实质并不相同,它是一个“附加值”。

不同的颜色模式之间的转换好像很容易,其实不然。虽然网上有很多转换公式,但几乎没有人提到色彩管理文件的概念。事实上,如果没有色彩管理文件,RGB 与 CMYK 颜色之间根本没有转换关系,因为它们都只是一个相对颜色。这样一来,我们的模型中必然要再引入色彩管理文件的概念,而不同颜色模式之间的转换是由相应的色彩管理文件进行的。于是,与颜色值本身相关的有两套类型:颜色模式(ColorMode)与色彩管理文件(ColorProfile)。ColorMode 用于定义混合颜色所用的通道信息,包括每个通道的名称、位深度、取值范围等等;而 ColorProfile 用于定义颜色模式与 Lab 绝对颜色之间的映射关系。

颜色模型之所以难以处理,其实并不在于 RGB、CMYK 等各种模式。当“通道色”概念出现以后,所有的不同模式都已经化归为一了。真正的麻烦在于颜色深度:除了位图是 1bpc(bit per channel)以外,还有 8bpc、16bpc 和 32bpc。当返回通道的值的时候,它们对应着完全不同的数据类型(Byte、Int16、Single)。返回类型是没法多态的,而这三种数据类型之间又存在的本质的差别(整数与浮点),无法在字节层面上统一运算。颜色概念本身的抽象、颜色类型的复杂度及处理数据的性能问题之间产生了巨大的矛盾。为了解决这个矛盾,我决定将浮点改为整型,将 32bpc 的颜色值使用 Int32 来存储和运算——事实上并不会丢失精度。于是,产生了一个特别的想法:将所有颜色的数据都视为连续的 Int32 数组,然后通过为每个精度设置掩码和偏移量,用位运算得到具体的通道分量。例如:ARGB 色 0xFF336699,R 通道的掩码就是 0x00FF0000,偏移量即 16,这样,就有:

r = (value & mask) >> offset

这个方式把位数长度也化归了,我曾一度认为这是一个完美的解决方案。然后很快就出现了新问题,像 CMYK 这样的颜色模型,加上 Alpha 通道就是 5 个分量,如果使用刚才的方式,一个颜色占用 8 个字节(2 个 Int32 长度),但却只有 5 个字节用来保存信息,3 个字节被严重浪费了。

带着这个问题,我又去研究了 Photoshop 的存储行为,想看看它会不会产生这种因字节对齐而导致的空间浪费。结果自然是没有,一个 100 像素的单层图像,RGB 模式下就是 400 字节(还要加上透明度),CMYK 模式下就是 500 字节,完全没有浪费。而更令我吃惊的是:如果图像并没有用到每个通道,或者是某个通道的内容完全是纯色的时候,这个通道根本不产生数据!也就是说,如果 RGB 模式下某图像的 R 通道内亮度没有任何变化的话,那就只有 300 字节的内存使用;如果连透明度也没有的话,就只有 200 字节的内存使用。这个现象证明 Photoshop 是以通道为单位来存储位图的,而不是像素。说得清楚一些就是:它将位图分成了若干个通道,每个通道是一个只包含亮度信息的灰度位图。

于是,颜色及位图的模型将再次经历一次洗礼。

原创粉丝点击