颜色类型的关系

来源:互联网 发布:js获取当前点击对象id 编辑:程序博客网 时间:2024/04/27 11:21

既然我们打算未来要支持那么多种颜色模式,那么用于表示颜色的也不可能像 GDI+ 那样一个单单的存储 8 位 ARGB 颜色的 Color 类型。很自然会想到,以 Color 类型为基类,派生出 RGB、CMYK、Lab 等各种具体的颜色模式。Color 类自身只需要维持一个用于保存实际颜色数据的字节数组的引用即可——它具体可以由各派生类来创建,因为不同的颜色模式和位数所需要的数据块长度不同。然后各个派生类从这个数据块中取出自己需要的部分。比如:表示 8 位 A-RGB 颜色的类可以创建一个 4 字节的数据块(data),然后将 data[0]、data[1]、data[2] 和 data[3] 分别表示 B、G、R、A 四个分量;而表示 16 位 A-CMYK 颜色的类则可以创建一个长度为 10 个字节的数据块,data[0] ~ data[1]、data[2] ~ data[3]、data[4] ~ data[5]、data[6] ~ data[7] 和 data[8] ~ data[9] 分别表示 K、Y、M、C 及 A 五个分量值。

问题产生于不同的颜色模式既可以按照色彩空间来分类,也可以按照颜色深度来分类。同样是 RGB 颜色模式,有 8 位、16 位、32 位三种。而同样是 16 位颜色深度,有 RGB、CMYK、Lab 三种。我们总是希望所有的类型最后都可以抽象为单独的 Color 类型,在绘图时,并不需要关心具体的颜色模式,只要相互一致即可。然而,C# 并不支持多重继承,这使得各颜色类型的关系建立非常困难。此外,还遇到了这样几个问题:

首先,各种色彩的绘制是按通道进行的,如果不考虑 Alpha 通道,那么只要简单的将新的通道值替换旧的即可。如果考虑 Alpha,则进行一个简单的混合运算。麻烦即在于,Color 基类拥有的仅仅是一个连续的字节数组,它无法知道自己包含多少通道,每个通道的字长是多少。

其次,当外界在大多数情况下只考虑 Color 这个基类型时,如何进行任意色彩模式之间的转换?不同的颜色空间,以及不同的颜色深度,都将影响色彩的转换。

除了大部分通道色之外,索引模式是不以通道进行处理的,它的像素点记录的也不是颜色信息,而是调色板编号。这将如何统一?索引到底应当视为颜色模式还是图像格式?

最后,跳出这堆类型,从外部来考虑,绘图软件在处理具体一幅图片的时候,其实是知道这张图片使用什么像素格式的,相关功能是否可用、通道面板里显示哪几个通道、信息面板以哪种方式显示真实色彩等等都是与图片的像素格式直接相关的。那么外部在调用这些色彩类型时,究竟有多少情况下会使用基类型,而多少情况下会指定具体的类型?如果经常需要检查类型,依靠反射肯定不是解决问题的办法。这样一来,这套色彩类型模型又将变成什么样?

原创粉丝点击