65.9K
CodeProject 正在变化。 阅读更多。
Home

色彩空间和转换

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.98/5 (32投票s)

2013年6月30日

GPL3

6分钟阅读

viewsIcon

154011

downloadIcon

4824

一个用于颜色模型和色彩空间、正确颜色转换和颜色差计算的库。

介绍  

我偶然发现了许多颜色转换库/工具,它们没有考虑到 RGB 颜色本身并没有被明确定义。了解 RGB 颜色值所属的确切 RGB 色彩空间(例如 sRGBAdobeRGBProPhotoRGB)非常重要,因为它们具有不同的参考白点、不同的伽马值和不同的色度坐标。同样,其他颜色模型也同样重要。

由于我需要为另一个软件提供这些功能,想多了解一些关于颜色方面的知识,并让互联网变得更好,所以我写了这个库。

还有一些小型 GUI: 

  • 转换:与所有支持的颜色模型进行相互转换
  • 颜色差:以多种方式计算两种颜色之间的差异
  • 速度:测量从一种颜色模型转换为另一种颜色模型所需的时间

背景  

库中包含几种不同的颜色模型和色彩空间

  • CIE XYZ (CIE 1931 2°) 
  • CIE Yxy (CIE 1931 2°) 
  • CIE L*a*b* (CIE 1976)
  • CIE L*u*v* (CIE 1976)
  • CIE LCHab
  • CIE LCHuv 
  • DIN99 (LCH99) 
  • DIN99b (LCH99b)
  • DIN99c (LCH99c)
  • DIN99d (LCH99d)
  • RGB 
    • NTSCRGB
    • BruceRGB
    • CIERGB
    • AdobeRGB
    • AppleRGB
    • ProPhotoRGB 
    • sRGB
    • WideGamutRGB
    • BestRGB
    • BetaRGB 
    • ColorMatchRGB
    • DonRGB4
    • EktaSpacePS5
    • PAL_SECAMRGB
    • SMPTE_C_RGB
  • HSV 
  • HSL
  • CMY
  • CMYK
  • YCbCr
    • ITU-R BT.601-625
    • ITU-R_BT.601-525
    • ITU-R-BT.709-1125
    • ITU-R BT.709-1250 
  • Gray
  • DEF
  • Bef
  • BCH
  • X-Channel Color (with X from 2 to 15)
  • ICC Profiles (alpha status)

还可以进行色度适应并更改参考白点。

这些颜色模型之间的转换如下所示

如果您想了解更多关于转换如何工作的信息: 

当然,您也可以查看代码(ColorManagment->Color_Conversion.cs #region Conversions)或者直接问我。

使用代码 

使用该库非常简单,但仍为您提供了定义或转换颜色的所有可能性。

让我们看一下 ColorConverter 类的静态部分。有一些设置将在不另行指定的情况下使用。这些设置是

  • ChromaticAdaptionMethod:用于转换的色度适应方法
  • ReferenceWhite:如果不另行指定,将用于颜色的参考白点
  • StandardColorspace:如果不另行指定,将使用的标准色彩空间
  • PreferredRenderingIntent:如果不另行指定且在 ICC 配置文件中可用,将使用的首选渲染意图
  • StandardYCbCrSpace:如果不另行指定,将用于 YCbCr 颜色的标准色彩空间

另外,在开始使用该库之前,您应该初始化 ColorConverter 类。如果您不初始化,不会出错,但这样一切都将得到受控的运行

ColorConverter.Init(); 

以下是一些创建新颜色的示例。还有一些其他可能性,您可以根据需要进行尝试。代码已记录,您将看到解释。

ColorRGB color = new ColorRGB(RGBSpaceName.sRGB);   //new RGB color in sRGB space
ColorRGB color = new ColorRGB(0, 0.5, 1);           //new RGB color in standard RGB space from settings
ColorRGB color = new ColorRGB(RGBSpaceName.sRGB, 0, 0.5, 1, true); //new linear RGB color in sRGB
ColorRGB color = new ColorRGB(new ICC("profile.icc"));  //new RGB color from an ICC profile
ColorLab color = new ColorLab(50, 12, -12); //new Lab color with reference white from settings
ColorLab color = new ColorLab(new Whitepoint(WhitepointName.D50));  //new Lab color with D50 reference white
ColorCMYK color = new ColorCMYK(new ICC("CMYKprofile.icc"));    //CMY(K) colors have to have an ICC profile

要将一种颜色转换为另一种颜色,请使用 ColorConverter 类。请注意,如果使用多线程,每个线程都必须拥有自己的 ColorConverter 类实例!

ColorConverter Converter = new ColorConverter();    //create a new instance of a ColorConverter
ColorLab lab = new ColorLab(50, 12, -12);  //create a Lab color
ColorRGB rgb = Converter.ToRGB(lab, RGBSpaceName.sRGB);  //convert it to an RGB color in AdobeRGB colorspace 
ColorConverter Converter = new ColorConverter();    //create a new instance of a ColorConverter
ColorRGB rgb = new ColorRGB(RGBSpaceName.AdobeRGB, 0, 0.5, 1);  //create an RGB color
ColorLab lab = Converter.ToLab(rgb, WhitepointName.D50);    //convert it to a Lab color with D50 reference white
ColorLab lab = Converter.ToLab(rgb);                        //or convert it to a Lab color with the default reference white 

使用 ICC 配置文件进行转换有点不同,可能尚未正确工作。由于缺乏不同的配置文件和与正确值的比较,我尚未对其进行彻底测试。尽管如此,我还是将其包含在此处,如果您发现任何错误/bug,请向我报告。 

ColorConverter Converter = new ColorConverter();    //create a new instance of a ColorConverter
ColorLab lab = new ColorLab(50, 12, -12);  //create a Lab color
ColorRGB rgb = (ColorRGB)Converter.ToICC(lab, new ICC("profile.icc"));  //convert a color with an ICC profile

要查找两种颜色之间的差异,请使用 ColorDifference 类(非多线程安全)

ColorLab lab1 = new ColorLab(0.5, 30, -12); //create the first Lab color
ColorLab lab2 = new ColorLab(0.5, 40, -2);  //create the second Lab color
double difference = ColorDifference.GetDeltaE_CIEDE2000(lab1, lab2);    //calculate the difference with CIE DE 2000 method 

或者使用 Din99c 方法

ColorLCH99c din1 = new ColorLCH99c(50, 12, 120);    //create the first DIN99c color
ColorLCH99c din2 = new ColorLCH99c(50, 16, 140);    //create the second DIN99c color
double difference = ColorDifference.GetDeltaE_DIN99(din1, din2);    //calculate the difference with the DIN99 method

对于某些方法,您也可以使用 GetDeltaC 来获取 Chroma(色度)差,使用 GetDeltaH 可以获取 Hue(色相)差。

对于色度适应,只需从一种 XYZ 颜色转换为另一种

ColorConverter Converter = new ColorConverter();    //create a new instance of a ColorConverter
ColorXYZ xyz = new ColorXYZ(new Whitepoint(WhitepointName.D50), 0, 0.5, 1);  //create a XYZ color with D50 reference white
xyz = Converter.ToXYZ(xyz, WhitepointName.D65);  //convert it to a XYZ color with a different reference white

如果需要在转换过程中进行色度适应,例如从 RGB 到 Lab,这当然会自动完成,您不必担心。我只是想提一下,您也可以显式地进行。

 自 3.0 版本以来,还有一个 Light 命名空间可用。它包含一些颜色模型,这些模型将所有值存储为字节(8 位 - BColor)或 ushort(16 位 - UColor),并且通常比标准颜色类更轻量级。轻量级类的工作方式与普通类相同,并且 ColorConverter 类也可用于转换。

使用 GUI  

转换 

如果您只是想知道某种颜色在其他色彩空间中的表示方式,可以使用此 GUI。输入您已知颜色的值,然后按框旁边的“Convert”按钮。 

  1. 点击此方块可从颜色选择器中选择 RGB 值 
  2. 通用设置
  3. 每种颜色的特定设置 

颜色差

要比较两种颜色,请使用此 GUI 以不同的方式查看计算出的差异。右侧是通用设置。要计算差异,请选择并设置您要比较的两种颜色,然后单击“Compare”。要设置值,请选择通道,然后在上面的文本框中输入值。结果将在下方显示。Delta E 是差异,Delta H 是色相差,Delta C 是色度差。 

速度

要查看转换速度,请使用此 GUI。您还可以看到多线程带来的差异。在右侧,您可以设置迭代次数、通用设置以及要使用的线程数。设置好颜色后,单击“Start”并等待结果。总时间是指所有迭代所花费的时间(以毫秒为单位),每次迭代的时间是指一次转换所需的平均时间(以微秒为单位)。

限制

如前所述,ICC 配置文件仍处于 alpha 状态,尚未经过彻底测试。如果您对 ICC 配置文件及其转换工作原理有所了解,我将非常感谢您的帮助。 而且由于它尚未真正完成,因此使用 ICC 配置文件进行转换的速度相当慢(与正常转换相比)。 

关注点   

好吧,学习所有这些色彩空间的工作原理确实让我好几次头疼,但现在(我认为)我理解了。所以,如果您对这里的任何内容的工作原理有任何疑问,请随时提问。

计划

对于未来的版本,我计划

  • 超出范围警告/检查
  • 渲染意图计算 
  • 更好、更快的 ICC 支持

历史

  • 2013 年 7 月 - 版本 1.0(库和 GUI) 
  • 2013 年 9 月 - 版本 2.0(库和三个 GUI) 
    • 更改了 RGB 颜色的结构
    • 将转换从颜色类分离到新的转换类
    • 添加了几个新的颜色模型
    • 添加了 ICC 支持
    • 添加了色度适应
    • 添加了颜色差类
    • 为颜色差和速度测量添加了 GUI
    • 大大提高了转换速度
  • 2013 年 11 月 - 版本 3.0(库和三个 GUI)
    • 修复了 LCHuv 计算中的一个错误
    • 修复了 Delta E CMC 计算中的一个错误
    • 修复了其他小错误
    • 修复了一个错误并在 Color.Copy() 中添加了 DIN99 颜色
    • 修复了 ColorDifference CMC 方法:Lab 需要 D65 参考白点
    • 添加了带自定义 l:c 值的 Delta E CMC 计算
    • 添加了从 DIN99c 和 DIN99d 到所有其他颜色模型的转换
    • 为颜色添加了 Light 版本:以字节或 ushort 存储值以减小内存占用
    • 添加了 DEF、Bef 和 BCH 颜色模型以及所有转换
© . All rights reserved.