zoukankan      html  css  js  c++  java
  • 几种颜色模型的转换公式

    在做图像处理时,我们一般采用的是RGB空间,但是在某些特殊情况下,我们也会用到其他的颜色空间。本文主要介绍一些常见的颜色空间的概念和转换公式。

    颜色的实质是一种光波。它的存在是因为有三个实体:光线、被观察的对象以及观察者。人眼是把颜色当作由被观察对象吸收或者反射不同波长的光波形成的。例如,当在一个晴朗的日子里,我们看到阳光下的某物体呈现红色时,那是因为该物体吸收了其它波长的光,而把红色波长的光反射到我们人眼里的缘故。当然,我们人眼所能感受到的只是波长在可见光范围内的光波信号。当各种不同波长的光信号一同进入我们的眼睛的某一点时,我们的视觉器官会将它们混合起来,作为一种颜色接受下来。同样我们在对图像进行颜色处理时,也要进行颜色的混合,但我们要遵循一定的规则,即我们是在不同颜色模式下对颜色进行处理的。

    1.RGB颜色模式

      虽然可见光的波长有一定的范围,但我们在处理颜色时并不需要将每一种波长的颜色都单独表示。因为自然界中所有的颜色都可以用红、绿、蓝(RGB)这三种颜色波长的不同强度组合而得,这就是人们常说的三基色原理。因此,这三种光常被人们称为三基色或三原色。有时候我们亦称这三种基色为添加色(Additive Colors),这是因为当我们把不同光的波长加到一起的时候,得到的将会是更加明亮的颜色。把三种基色交互重叠,就产生了次混合色:青(Cyan)、洋红(Magenta)、黄(Yellow)。这同时也引出了互补色(Complement Colors)的概念。基色和次混合色是彼此的互补色,即彼此之间最不一样的颜色。例如青色由蓝色和绿色构成,而红色是缺少的一种颜色,因此青色和红色构成了彼此的互补色。在数字视频中,对RGB三基色各进行8位编码就构成了大约16.7万种颜色,这就是我们常说的真彩色。顺便提一句,电视机和计算机的监视器都是基于RGB颜色模式来创建其颜色的。

    2.Lab颜色模式

      Lab颜色是由RGB三基色转换而来的,它是由RGB模式转换为HSB模式和CMYK模式的桥梁。该颜色模式由一个发光率(Luminance)和两个颜色(a,b)轴组成。它由颜色轴所构成的平面上的环形线来表示颜色的变化,其中径向表示色饱和度的变化,自内向外,饱和度逐渐增高;圆周方向表示色调的变化,每个圆周形成一个色环;而不同的发光率表示不同的亮度并对应不同环形颜色变化线。它是一种具有“独立于设备”的颜色模式,即不论使用任何一种监视器或者打印机,Lab的颜色不变。

    RGB=>Lab

    |X|   |0.433910  0.376220  0.189860| |R/255|
    |Y| = |0.212649  0.715169  0.072182|*|G/255|
    |Z|   |0.017756  0.109478  0.872915| |B/255|
    
    L = 116*Y

    1/3

          for Y>0.008856
    L = 903.3*Y      for Y<=0.008856
    
    a = 500*(f(X)-f(Y))
    b = 200*(f(Y)-f(Z))
    其中  f(t)=t

    1/3

                  for t>0.008856
          f(t)=7.787*t+16/116    for t<=0.008856

    3.HSB颜色模式

      从心理学的角度来看,颜色有三个要素:色泽(Hue)、饱和度(Saturation)和亮度(Brightness)。HSB颜色模式便是基于人对颜色的心理感受的一种颜色模式。它是由RGB三基色转换为Lab模式,再在Lab模式的基础上考虑了人对颜色的心理感受这一因素而转换成的。因此这种颜色模式比较符合人的视觉感受,让人觉得更加直观一些。它可由底与底对接的两个圆锥体立体模型来表示,其中轴向表示亮度,自上而下由白变黑;径向表示色饱和度,自内向外逐渐变高;而圆周方向,则表示色调的变化,形成色环。

    RGB=>HSB

    V=max(R,G,B)
    S=(V-min(R,G,B))*255/V   if V!=0, 0 otherwise
    
           (G - B)*60/S,  if V=R
    H= 180+(B - R)*60/S,  if V=G
       240+(R - G)*60/S,  if V=B
    
    若 H<0,则 H=H+360
    

    使用上面从 0° 到 360° 变化的公式计算色调( hue)值,确保它们被 2 除后能试用于8位。

    4.YUV颜色模式

      这是电视系统中常用的颜色模式,即电视中所谓的分量(Component)信号。该模式由一个亮度信号Y和两个色差信号U、V组成。它是利用了人眼对亮度信号敏感而对色度信号相对不敏感的特点,将RGB颜色通过亮度信号公式Y=0�39R+0�50G+0�11B转换为一个亮度信号Y和两个色差分量信号U(R-Y)、V(B-Y),即对色差信号进行了频带压缩。毫无疑问,这是以牺牲信号的质量为代价的。

    RGB<=>YUV
    Y = 0.299R + 0.587G + 0.114B
    U = -0.147R - 0.289G + 0.436B
    V = 0.615R - 0.515G - 0.100B
    
    R = Y + 1.14V
    G = Y - 0.39U - 0.58V
    B = Y + 2.03U

    5.CMYK颜色模式

      这是彩色印刷使用的一种颜色模式。它由青(Cyan)、洋红(Magenta)、黄(Yellow)和黑(Black)四种颜色组成。其中黑色之所以用K来表示,是为避免和RGB三基色中的蓝色(Blue,用B表示)发生混淆。该种模式的创建基础和RGB不同,它不是靠增加光线,而是靠减去光线,因为和监视器或者电视机不同的是,打印纸不能创建光源,它不会发射光线,只能吸收和反射光线。因此通过对上述四种颜色的组合,便可以产生可见光谱中的绝大部分颜色了。

    RGB<=CMYK

       R = (255 - C) * ((255 - K) / 255) 
        G = (255 - M) * ((255 - K) / 255) 
        B = (255 - Y) * ((255 - K) / 255) 

     
     


    6.部分程序code

    void HSI2RGB(BYTE &BR,BYTE &BG,BYTE &BB,BYTE BH,BYTE BS,BYTE BI)
    {
    int nHValue = static_cast<int>(BH);
    int nSValue = static_cast<int>(BS);
    int nLValue = static_cast<int>(BI);

    float fHAngle = ((float)nHValue ) / 255 * 360;

    float H = fHAngle / 180 * PI;
    float S = ((float)nSValue ) / 100;
    float I = ((float)nLValue ) / 100;

    float R = -1;
    float G = -1;
    float B = -1;

    if(fHAngle >= 0 && fHAngle < 120)
    {
      B = I * ( 1.0 - S );
      R = I * ( 1.0 + ( S * cos( H ) / cos( 60.0 / 180 * PI - H ) ) ); 
      G = 3.0 * I - ( B + R );
    }
    else if(fHAngle >= 120 && fHAngle < 240)
    {
      R = I * ( 1.0 - S );
      G = I * ( 1.0 + S * cos( H - 120.0 / 180 * PI ) / cos( 180.0 / 180 * PI - H )  );
      B = 3.0 * I - ( R + G );
    }
    else if(fHAngle >= 240 && fHAngle < 360)
    {
      G = I * ( 1.0 - S );
      B = I * ( 1.0 + S * cos( H - 240.0 / 180 * PI ) / cos( 300.0 / 180 * PI - H ) );
      R = 3.0 * I - ( G + B );
    }
    int R_value_in_rgb = R * 255;
    int G_value_in_rgb = G * 255;
    int B_value_in_rgb = B * 255;
    BR = static_cast<BYTE>(R_value_in_rgb);
    BG = static_cast<BYTE>(G_value_in_rgb);
    BB = static_cast<BYTE>(B_value_in_rgb);
    }

    void  RGB2HSI(BYTE r,BYTE g,BYTE b,BYTE &h,BYTE &s,BYTE &i)
    {
    short m_fr = static_cast<short>(r);
    short m_fg = static_cast<short>(g);
    short m_fb = static_cast<short>(b);

    float m_fiR = static_cast<float>(m_fr) / 255;
    float m_fsG = static_cast<float>(m_fg) / 255;
    float m_fhB = static_cast<float>(m_fb) / 255;
      
    if( m_fr == m_fg && m_fg == m_fb)
    {
      int iHValue = 0;
      int iSValue = 0;
      int iLValue = ((float)m_fr)/ 255 * 100;
      h = static_cast<BYTE>(iHValue);
      s = static_cast<BYTE>(iSValue);
      i = static_cast<BYTE>(iLValue);  
      return;
    }
    float max_value_of_rgb = GetMax( m_fiR, m_fsG, m_fhB );
    float min_value_of_rgb = GetMin( m_fiR, m_fsG, m_fhB );
    float fSumRGB =m_fiR + m_fsG + m_fhB ;
    if( fSumRGB <= 0.0 )
      fSumRGB = 0.001;
    float I = (m_fiR + m_fsG + m_fhB) / 3;
    float S = 1.0 - 3.0 * min_value_of_rgb / fSumRGB;
    float H = acos( (( m_fiR - m_fsG ) + ( m_fiR - m_fhB ))/2 / sqrt( ( m_fiR - m_fsG )*( m_fiR - m_fsG ) + ( m_fiR -m_fhB ) * ( m_fsG - m_fhB)  + 0.0001 ) );
    float fHAngle = H / PI * 180;
    if( m_fsG < m_fhB )
      fHAngle = 360 - fHAngle;
    if( fHAngle > 360.0 )
      fHAngle = 360.0;
    int nHValue = fHAngle / 360 * 255;
    int nSValue = S * 100;
    int nLValue = I * 100;
    h = nHValue;
    s = nSValue;
    i = nLValue;
    }

     

    先来了解一些概念:

    1.RGB是一种加色模型,就是将不同比例的Red/Green/Blue混合在一起得到新颜色.通常RGB颜色模型表示为:

    image

    2.HSB(HSV) 通过色相/饱和度/亮度三要素来表达颜色.

      H(Hue):表示颜色的类型(例如红色,绿色或者黄色).取值范围为0—360.其中每一个值代表一种颜色.

      S(Saturation):颜色的饱和度.从0到1.有时候也称为纯度.(0表示灰度图,1表示纯的颜色)

      B(Brightness or Value):颜色的明亮程度.从0到1.(0表示黑色,1表示特定饱和度的颜色)

     

      image

     

    后面地址是一个在线的观察RGB到HSB转换的工具:http://web.bentley.edu/empl/c/ncarter/MA307/color-converter.html

    用RGB来表示颜色虽然方便,但是两个相近的颜色的RGB值却可能相差十万八千里。用HSV(Hue色相、Saturation饱和度、Value(Brightness)明度,也叫HSB)来表示颜色就比较符合人们的习惯。

    RGB到HSV(HSB)的转换:

    HSV(HSB)到RGB的转换:


    根据以上说明,有以下转换公式(Java代码)

     

    [java] view plaincopy
     
    1. public static float[] rgb2hsb(int rgbR, int rgbG, int rgbB) { 
    2.     assert 0 <= rgbR && rgbR <= 255; 
    3.     assert 0 <= rgbG && rgbG <= 255; 
    4.     assert 0 <= rgbB && rgbB <= 255; 
    5.     int[] rgb = new int[] { rgbR, rgbG, rgbB }; 
    6.     Arrays.sort(rgb); 
    7.     int max = rgb[2]; 
    8.     int min = rgb[0]; 
    9.  
    10.     float hsbB = max / 255.0f; 
    11.     float hsbS = max == 0 ? 0 : (max - min) / (float) max; 
    12.  
    13.     float hsbH = 0; 
    14.     if (max == rgbR && rgbG >= rgbB) { 
    15.         hsbH = (rgbG - rgbB) * 60f / (max - min) + 0; 
    16.     } else if (max == rgbR && rgbG < rgbB) { 
    17.         hsbH = (rgbG - rgbB) * 60f / (max - min) + 360; 
    18.     } else if (max == rgbG) { 
    19.         hsbH = (rgbB - rgbR) * 60f / (max - min) + 120; 
    20.     } else if (max == rgbB) { 
    21.         hsbH = (rgbR - rgbG) * 60f / (max - min) + 240; 
    22.     } 
    23.  
    24.     return new float[] { hsbH, hsbS, hsbB }; 
    25.  
    26. public static int[] hsb2rgb(float h, float s, float v) { 
    27.     assert Float.compare(h, 0.0f) >= 0 && Float.compare(h, 360.0f) <= 0; 
    28.     assert Float.compare(s, 0.0f) >= 0 && Float.compare(s, 1.0f) <= 0; 
    29.     assert Float.compare(v, 0.0f) >= 0 && Float.compare(v, 1.0f) <= 0; 
    30.  
    31.     float r = 0, g = 0, b = 0; 
    32.     int i = (int) ((h / 60) % 6); 
    33.     float f = (h / 60) - i; 
    34.     float p = v * (1 - s); 
    35.     float q = v * (1 - f * s); 
    36.     float t = v * (1 - (1 - f) * s); 
    37.     switch (i) { 
    38.     case 0: 
    39.         r = v; 
    40.         g = t; 
    41.         b = p; 
    42.         break; 
    43.     case 1: 
    44.         r = q; 
    45.         g = v; 
    46.         b = p; 
    47.         break; 
    48.     case 2: 
    49.         r = p; 
    50.         g = v; 
    51.         b = t; 
    52.         break; 
    53.     case 3: 
    54.         r = p; 
    55.         g = q; 
    56.         b = v; 
    57.         break; 
    58.     case 4: 
    59.         r = t; 
    60.         g = p; 
    61.         b = v; 
    62.         break; 
    63.     case 5: 
    64.         r = v; 
    65.         g = p; 
    66.         b = q; 
    67.         break; 
    68.     default: 
    69.         break; 
    70.     } 
    71.     return new int[] { (int) (r * 255.0), (int) (g * 255.0), 
    72.             (int) (b * 255.0) }; 

     

     

     

    几种颜色模型的转换公式

    XYZ —> RGB

    var_X = X / 100        //X from 0 to  95.047    
    var_Y = Y / 100        //Y from 0 to 100.000
    var_Z = Z / 100        //Z from 0 to 108.883

    var_R = var_X *  3.2406 + var_Y * -1.5372 + var_Z * -0.4986
    var_G = var_X * -0.9689 + var_Y *  1.8758 + var_Z *  0.0415
    var_B = var_X *  0.0557 + var_Y * -0.2040 + var_Z *  1.0570

    if ( var_R > 0.0031308 ) var_R = 1.055 * ( var_R ^ ( 1 / 2.4 ) ) - 0.055
    else                     var_R = 12.92 * var_R
    if ( var_G > 0.0031308 ) var_G = 1.055 * ( var_G ^ ( 1 / 2.4 ) ) - 0.055
    else                     var_G = 12.92 * var_G
    if ( var_B > 0.0031308 ) var_B = 1.055 * ( var_B ^ ( 1 / 2.4 ) ) - 0.055
    else                     var_B = 12.92 * var_B

    R = var_R * 255
    G = var_G * 255
    B = var_B * 255

     

     

    RGB —> XYZ

    var_R = ( R / 255 )        //R from 0 to 255
    var_G = ( G / 255 )        //G from 0 to 255
    var_B = ( B / 255 )        //B from 0 to 255

    if ( var_R > 0.04045 ) var_R = ( ( var_R + 0.055 ) / 1.055 ) ^ 2.4
    else                   var_R = var_R / 12.92
    if ( var_G > 0.04045 ) var_G = ( ( var_G + 0.055 ) / 1.055 ) ^ 2.4
    else                   var_G = var_G / 12.92
    if ( var_B > 0.04045 ) var_B = ( ( var_B + 0.055 ) / 1.055 ) ^ 2.4
    else                   var_B = var_B / 12.92

    var_R = var_R * 100
    var_G = var_G * 100
    var_B = var_B * 100

    X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805
    Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722
    Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505

     

     

    XYZ —> Yxy

    //X from 0 to 95.047      

    //Y from 0 to 100.000
    //Z from 0 to 108.883

    Y = Y
    x = X / ( X + Y +Z )
    y = Y / ( X + Y +Z )

     

     

     

    Yxy —> XYZ

    //Y from 0 to 100
    //x from 0 to 1
    //y from 0 to 1

    X = x * ( Y / y )
    Y = Y
    Z = ( 1 - x - y ) * ( Y / y )

     

     

    XYZ —> Hunter-Lab

    (H)L = 10 * sqrt( Y )
    (H)a = 17.5 * ( ( ( 1.02 * X ) - Y ) / sqrt(Y ) )
    (H)b = 7 * ( ( Y - ( 0.847 * Z ) ) / sqrt(Y ) )

     

     

    Hunter-Lab —> XYZ

    var_Y = (H)L / 10
    var_X = (H)a / 17.5 * (H)L / 10
    var_Z = (H)b / 7 * (H)L / 10

    Y = var_Y ^ 2
    X = ( var_X + Y ) / 1.02
    Z = -( var_Z - Y ) / 0.847

     

     

    XYZ —> CIE-L*ab

    var_X = X / ref_X          //ref_X =  95.047 

    var_Y = Y / ref_Y          //ref_Y = 100.000
    var_Z = Z / ref_Z          //ref_Z = 108.883

    if ( var_X > 0.008856 ) var_X = var_X ^ ( 1/3 )
    else                    var_X = ( 7.787 * var_X ) + ( 16 / 116 )
    if ( var_Y > 0.008856 ) var_Y = var_Y ^ ( 1/3 )
    else                    var_Y = ( 7.787 * var_Y ) + ( 16 / 116 )
    if ( var_Z > 0.008856 ) var_Z = var_Z ^ ( 1/3 )
    else                    var_Z = ( 7.787 * var_Z ) + ( 16 / 116 )

    CIE-L* = ( 116 * var_Y ) - 16
    CIE-a* = 500 * ( var_X - var_Y )
    CIE-b* = 200 * ( var_Y - var_Z )

     

     

    CIE-L*ab —> XYZ

    var_Y = ( CIE-L* + 16 ) / 116
    var_X = CIE-a* / 500 + var_Y
    var_Z = var_Y - CIE-b* / 200

    if ( var_Y^3 > 0.008856 ) var_Y = var_Y^3
    else                      var_Y = ( var_Y - 16 / 116 ) / 7.787
    if ( var_X^3 > 0.008856 ) var_X = var_X^3
    else                      var_X = ( var_X - 16 / 116 ) / 7.787
    if ( var_Z^3 > 0.008856 ) var_Z = var_Z^3
    else                      var_Z = ( var_Z - 16 / 116 ) / 7.787

    X = ref_X * var_X     //ref_X =  95.047    

    Y = ref_Y * var_Y     //ref_Y = 100.000
    Z = ref_Z * var_Z     //ref_Z = 108.883

     

     

    CIE-L*ab —> CIE-L*CH°

    var_H = arc_tangent( CIE-b*CIE-a* )  //Quadrant by signs

    if ( var_H > 0 ) var_H = ( var_H / PI ) * 180
    else             var_H = 360 - ( abs( var_H ) / PI ) * 180

    CIE-L* = CIE-L*
    CIE-C* = sqrt( CIE-a* ^ 2 + CIE-b* ^ 2 )
    CIE-H° = var_H

     

     

     

     

    CIE-L*CH° —>CIE-L*ab

    //CIE-H° from 0 to 360°

    CIE-L* = CIE-L*
    CIE-a* = cos( degree_2_radian( CIE-H° ) ) *CIE-C*
    CIE-b* = sin( degree_2_radian( CIE-H° ) ) *CIE-C*

     

     

    XYZ —> CIE-L*uv

    var_U = ( 4 * X ) / ( X + ( 15 * Y ) + ( 3 * Z ) )
    var_V = ( 9 * Y ) / ( X + ( 15 * Y ) + ( 3 *Z ) )

    var_Y = Y / 100
    if ( var_Y > 0.008856 ) var_Y = var_Y ^ ( 1/3 )
    else                    var_Y = ( 7.787 * var_Y ) + ( 16 / 116 )

    ref_X =  95.047     
    ref_Y = 100.000
    ref_Z = 108.883

    ref_U = ( 4 * ref_X ) / ( ref_X + ( 15 * ref_Y ) + ( 3 * ref_Z ) )
    ref_V = ( 9 * ref_Y ) / ( ref_X + ( 15 * ref_Y ) + ( 3 * ref_Z ) )

    CIE-L* = ( 116 * var_Y ) - 16
    CIE-u* = 13 * CIE-L* * ( var_U - ref_U )
    CIE-v* = 13 * CIE-L* * ( var_V - ref_V )

     

     

    CIE-L*uv —> XYZ

    var_Y = ( CIE-L* + 16 ) / 116
    if ( var_Y^3 > 0.008856 ) var_Y = var_Y^3
    else                      var_Y = ( var_Y - 16 / 116 ) / 7.787

    ref_X =  95.047    
    ref_Y = 100.000
    ref_Z = 108.883

    ref_U = ( 4 * ref_X ) / ( ref_X + ( 15 * ref_Y ) + ( 3 * ref_Z ) )
    ref_V = ( 9 * ref_Y ) / ( ref_X + ( 15 * ref_Y ) + ( 3 * ref_Z ) )

    var_U = CIE-u* / ( 13 * CIE-L* ) + ref_U
    var_V = CIE-v* / ( 13 * CIE-L* ) + ref_V

    Y = var_Y * 100
    X =  - ( 9 * Y * var_U ) / ( ( var_U - 4 ) * var_V  - var_U * var_V )
    Z = ( 9 * Y - ( 15 * var_V * Y ) - ( var_V * X ) ) / ( 3 * var_V )

     

     

    RGB —> HSL

    var_R = ( R / 255 )                     //RGB from 0 to 255
    var_G = ( G / 255 )
    var_B = ( B / 255 )

    var_Min = min( var_R, var_G, var_B )    //Min. value of RGB
    var_Max = max( var_R, var_G, var_B )    //Max. value of RGB
    del_Max = var_Max - var_Min             //Delta RGB value

    L = ( var_Max + var_Min ) / 2

    if ( del_Max == 0 )                     //This is a gray, no chroma...
    {
       H = 0                                //HSL results from 0 to 1
       S = 0
    }
    else                                    //Chromatic data...
    {
       if ( L < 0.5 ) S = del_Max / ( var_Max + var_Min )
       else           S = del_Max / ( 2 - var_Max - var_Min )

       del_R = ( ( ( var_Max - var_R ) / 6 ) + ( del_Max / 2 ) ) / del_Max
       del_G = ( ( ( var_Max - var_G ) / 6 ) + ( del_Max / 2 ) ) / del_Max
       del_B = ( ( ( var_Max - var_B ) / 6 ) + ( del_Max / 2 ) ) / del_Max

       if      ( var_R == var_Max ) H = del_B - del_G
       else if ( var_G == var_Max ) H = ( 1 / 3 ) + del_R - del_B
       else if ( var_B == var_Max ) H = ( 2 / 3 ) + del_G - del_R

       if ( H < 0 ) ; H += 1
       if ( H > 1 ) ; H -= 1
    }

     

     

     

    HSL —> RGB

    if ( S == 0 )                      //HSL from 0 to 1
    {
       R = L * 255                      //RGB results from 0 to 255
       G = L * 255
       B = L * 255
    }
    else
    {
       if ( L < 0.5 ) var_2 = L * ( 1 + S )
       else           var_2 = ( L + S ) - ( S * L )

       var_1 = 2 * L - var_2

       R = 255 * Hue_2_RGB( var_1, var_2, H + ( 1 / 3 ) )
       G = 255 * Hue_2_RGB( var_1, var_2, H )
       B = 255 * Hue_2_RGB( var_1, var_2, H - ( 1 / 3 ) )
    }

    Hue_2_RGB( v1, v2, vH )             //Function Hue_2_RGB
    {
       if ( vH < 0 ) vH += 1
       if ( vH > 1 ) vH -= 1
       if ( ( 6 * vH ) < 1 ) return ( v1 + ( v2 - v1 ) * 6 * vH )
       if ( ( 2 * vH ) < 1 ) return ( v2 )
       if ( ( 3 * vH ) < 2 ) return ( v1 + ( v2 - v1 ) * ( ( 2 / 3 ) - vH ) * 6 )
       return ( v1 )
    }

     

     

    RGB —> HSV

    var_R = ( R / 255 )                     //RGB from 0 to 255
    var_G = ( G / 255 )
    var_B = ( B / 255 )

    var_Min = min( var_R, var_G, var_B )    //Min. value of RGB
    var_Max = max( var_R, var_G, var_B )    //Max. value of RGB
    del_Max = var_Max - var_Min             //Delta RGB value

    V = var_Max

    if ( del_Max == 0 )                     //This is a gray, no chroma...
    {
       H = 0                                //HSV results from 0 to 1
       S = 0
    }
    else                                    //Chromatic data...
    {
       S = del_Max / var_Max

       del_R = ( ( ( var_Max - var_R ) / 6 ) + ( del_Max / 2 ) ) / del_Max
       del_G = ( ( ( var_Max - var_G ) / 6 ) + ( del_Max / 2 ) ) / del_Max
       del_B = ( ( ( var_Max - var_B ) / 6 ) + ( del_Max / 2 ) ) / del_Max

       if      ( var_R == var_Max ) H = del_B - del_G
       else if ( var_G == var_Max ) H = ( 1 / 3 ) + del_R - del_B
       else if ( var_B == var_Max ) H = ( 2 / 3 ) + del_G - del_R

       if ( H < 0 ) ; H += 1
       if ( H > 1 ) ; H -= 1
    }

     

     

    HSV —> RGB

    if ( S == 0 )                       //HSV from 0 to 1
    {
       R = V * 255
       G = V * 255
       B = V * 255
    }
    else
    {
       var_h = H * 6
       if ( var_h == 6 ) var_h = 0      //H must be < 1
       var_i = int( var_h )             //Or ... var_i = floor( var_h )
       var_1 = V * ( 1 - S )
       var_2 = V * ( 1 - S * ( var_h - var_i ) )
       var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) )

       if      ( var_i == 0 ) { var_r = V     ; var_g = var_3 ; var_b = var_1 }
       else if ( var_i == 1 ) { var_r = var_2 ; var_g = V     ; var_b = var_1 }
       else if ( var_i == 2 ) { var_r = var_1 ; var_g = V     ; var_b = var_3 }
       else if ( var_i == 3 ) { var_r = var_1 ; var_g = var_2 ; var_b = V   }
       else if ( var_i == 4 ) { var_r = var_3 ; var_g = var_1 ; var_b = V   }
       else                   { var_r = V     ; var_g = var_1 ; var_b = var_2 }

       R = var_r * 255                  //RGB results from 0 to 255
       G = var_g * 255
       B = var_b * 255
    }

     

     

    RGB —> CMY

    //RGB values from 0 to 255
    //CMY results from 0 to 1

    C = 1 - ( R / 255 )
    M = 1 - ( G / 255 )
    Y = 1 - ( B / 255 )

     

     

    CMY —> RGB

    //CMY values from 0 to 1
    //RGB results from 0 to 255

    R = ( 1 - C ) * 255
    G = ( 1 - M ) * 255

    B = ( 1 - Y ) * 255

     

     

    CMY —> CMYK

    //CMYK and CMY values from 0 to 1

    var_K = 1

    if ( C < var_K )   var_K = C
    if ( M < var_K )   var_K = M
    if ( Y < var_K )   var_K = Y
    if ( var_K == 1 ) { //Black
       C = 0
       M = 0
       Y = 0
    }
    else {
       C
     = ( C - var_K ) / ( 1 - var_K )

       M = ( M - var_K ) / ( 1 - var_K )
       Y = ( Y - var_K ) / ( 1 - var_K )
    }
    K = var_K

     

     

    CMYK —> CMY

    //CMYK and CMY values from 0 to 1

    C = ( C * ( 1 - K ) +K )
    M = ( M * ( 1 - ) + K )
    Y = ( Y * ( 1 - ) + K )

  • 相关阅读:
    多线程 java 同步 、锁 、 synchronized 、 Thread 、 Runnable
    装饰设计模式 Decorator
    Java File IO 字节字符流
    觉得 eclipse 不好用的,了解一下快捷键,辅助快捷输入 类创建方式
    Power builder PB 使用 相关记录
    java 多态 深入理解多态-隐藏-低调-伪装
    Idea 出现 Error:java: Compilation failed: internal java compiler error
    Access 导入到 SQLServer
    20200117 .net 001
    Android ConstraintLayout详解(from jianshu)
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4831903.html
Copyright © 2011-2022 走看看