RGB和HSL颜色转换

 
  1. //   
  2.   
  3. // 下面的代码完成颜色转换:RGB<--->HSL。注意它们的分量的取值范围。   
  4.   
  5. // cheungmine 收集整理   
  6.   
  7. //   
  8.  
  9. #include "stdafx.h"   
  10.  
  11.  
  12.  
  13. #define min3v(v1, v2, v3)   ((v1)>(v2)? ((v2)>(v3)?(v3):(v2)):((v1)>(v3)?(v3):(v2)))   
  14.   
  15. #define max3v(v1, v2, v3)   ((v1)<(v2)? ((v2)<(v3)?(v3):(v2)):((v1)<(v3)?(v3):(v1)))  
  16.   
  17.   
  18.   
  19. typedef struct   
  20.   
  21. {  
  22.   
  23.     BYTE  red;              // [0,255]   
  24.   
  25.     BYTE  green;            // [0,255]   
  26.   
  27.     BYTE  blue;             // [0,255]   
  28.   
  29. }COLOR_RGB;  
  30.   
  31.   
  32.   
  33. typedef struct   
  34.   
  35. {  
  36.   
  37.     float  hue;               // [0,360]   
  38.   
  39.     float  saturation;        // [0,100]   
  40.   
  41.     float  luminance;         // [0,100]   
  42.   
  43. }COLOR_HSL;  
  44.   
  45.   
  46.   
  47. // Converts RGB to HSL   
  48.   
  49. static   void  RGBtoHSL( /*[in]*/ const  COLOR_RGB *rgb,  /*[out]*/ COLOR_HSL *hsl)  
  50.   
  51. {  
  52.   
  53.     float  h=0, s=0, l=0;  
  54.   
  55.   
  56.   
  57.     // normalizes red-green-blue values   
  58.   
  59.     float  r = rgb->red/255.f;  
  60.   
  61.     float  g = rgb->green/255.f;  
  62.   
  63.     float  b = rgb->blue/255.f;  
  64.   
  65.   
  66.   
  67.     float  maxVal = max3v(r, g, b);  
  68.   
  69.     float  minVal = min3v(r, g, b);  
  70.   
  71.   
  72.   
  73.     // hue   
  74.   
  75.     if (maxVal == minVal)  
  76.   
  77.     {  
  78.   
  79.         h = 0; // undefined   
  80.   
  81.     }  
  82.   
  83.     else   if (maxVal==r && g>=b)  
  84.   
  85.     {  
  86.   
  87.         h = 60.0f*(g-b)/(maxVal-minVal);  
  88.   
  89.     }  
  90.   
  91.     else   if (maxVal==r && g<b)  
  92.   
  93.     {  
  94.   
  95.         h = 60.0f*(g-b)/(maxVal-minVal) + 360.0f;  
  96.   
  97.     }  
  98.   
  99.     else   if (maxVal==g)  
  100.   
  101.     {  
  102.   
  103.         h = 60.0f*(b-r)/(maxVal-minVal) + 120.0f;  
  104.   
  105.     }  
  106.   
  107.     else   if (maxVal==b)  
  108.   
  109.     {  
  110.   
  111.         h = 60.0f*(r-g)/(maxVal-minVal) + 240.0f;  
  112.   
  113.     }  
  114.   
  115.   
  116.   
  117.     // luminance   
  118.   
  119.     l = (maxVal+minVal)/2.0f;  
  120.   
  121.   
  122.   
  123.     // saturation   
  124.   
  125.     if (l == 0 || maxVal == minVal)  
  126.   
  127.     {  
  128.   
  129.         s = 0;  
  130.   
  131.     }  
  132.   
  133.     else   if (0<l && l<=0.5f)  
  134.   
  135.     {  
  136.   
  137.         s = (maxVal-minVal)/(maxVal+minVal);  
  138.   
  139.     }  
  140.   
  141.     else   if (l>0.5f)  
  142.   
  143.     {  
  144.   
  145.         s = (maxVal-minVal)/(2 - (maxVal+minVal)); //(maxVal-minVal > 0)?   
  146.   
  147.     }  
  148.   
  149.   
  150.   
  151.     hsl->hue = (h>360)? 360 : ((h<0)?0:h);   
  152.   
  153.     hsl->saturation = ((s>1)? 1 : ((s<0)?0:s))*100;  
  154.   
  155.     hsl->luminance = ((l>1)? 1 : ((l<0)?0:l))*100;  
  156.   
  157. }   
  158.   
  159.   
  160.   
  161. // Converts HSL to RGB   
  162.   
  163. static   void  HSLtoRGB( const  COLOR_HSL *hsl, COLOR_RGB *rgb)   
  164.   
  165. {  
  166.   
  167.     float  h = hsl->hue;                   // h must be [0, 360]   
  168.   
  169.     float  s = hsl->saturation/100.f;  // s must be [0, 1]   
  170.   
  171.     float  l = hsl->luminance/100.f;       // l must be [0, 1]   
  172.   
  173.     float  R, G, B;  
  174.   
  175.   
  176.   
  177.     if (hsl->saturation == 0)  
  178.   
  179.     {  
  180.   
  181.         // achromatic color (gray scale)   
  182.   
  183.         R = G = B = l*255.f;  
  184.   
  185.     }  
  186.   
  187.     else   
  188.   
  189.     {  
  190.   
  191.         float  q = (l<0.5f)?(l * (1.0f+s)):(l+s - (l*s));  
  192.   
  193.         float  p = (2.0f * l) - q;  
  194.   
  195.   
  196.   
  197.         float  Hk = h/360.0f;  
  198.   
  199.         float  T[3];  
  200.   
  201.         T[0] = Hk + 0.3333333f; // Tr   0.3333333f=1.0/3.0   
  202.   
  203.         T[1] = Hk;              // Tb   
  204.   
  205.         T[2] = Hk - 0.3333333f; // Tg   
  206.   
  207.   
  208.   
  209.         for ( int  i=0; i<3; i++)  
  210.   
  211.         {  
  212.   
  213.             if (T[i] < 0) T[i] += 1.0f;  
  214.   
  215.             if (T[i] > 1) T[i] -= 1.0f;  
  216.   
  217.   
  218.   
  219.             if ((T[i]*6) < 1)  
  220.   
  221.             {  
  222.   
  223.                 T[i] = p + ((q-p)*6.0f*T[i]);  
  224.   
  225.             }  
  226.   
  227.             else   if ((T[i]*2.0f) < 1)  //(1.0/6.0)<=T[i] && T[i]<0.5   
  228.   
  229.             {  
  230.   
  231.                 T[i] = q;  
  232.   
  233.             }  
  234.   
  235.             else   if ((T[i]*3.0f) < 2)  // 0.5<=T[i] && T[i]<(2.0/3.0)   
  236.   
  237.             {  
  238.   
  239.                 T[i] = p + (q-p) * ((2.0f/3.0f) - T[i]) * 6.0f;  
  240.   
  241.             }  
  242.   
  243.             else  T[i] = p;  
  244.   
  245.         }  
  246.   
  247.   
  248.   
  249.         R = T[0]*255.0f;  
  250.   
  251.         G = T[1]*255.0f;  
  252.   
  253.         B = T[2]*255.0f;  
  254.   
  255.     }  
  256.   
  257.       
  258.   
  259.     rgb->red = (BYTE)((R>255)? 255 : ((R<0)?0 : R));  
  260.   
  261.     rgb->green = (BYTE)((G>255)? 255 : ((G<0)?0 : G));  
  262.   
  263.     rgb->blue = (BYTE)((B>255)? 255 : ((B<0)?0 : B));  
  264.   
  265. }  
  266.   
  267.   
  268.   
  269.   
  270.   
  271. int  _tmain( int  argc, _TCHAR* argv[])  
  272.   
  273. {  
  274.   
  275.     COLOR_RGB  rgb={254, 216, 166};  
  276.   
  277.     COLOR_HSL  hsl;  
  278.   
  279.       
  280.   
  281.     RGBtoHSL(&rgb, &hsl);  
  282.   
  283.     printf("H=%.0f; S=%.0f; L=%.0f/n" , hsl.hue, hsl.saturation, hsl.luminance);  
  284.   
  285.   
  286.   
  287.     HSLtoRGB(&hsl, &rgb);  
  288.   
  289.     RGBtoHSL(&rgb, &hsl);  
  290.   
  291.     printf("H=%.0f; S=%.0f; L=%.0f/n" , hsl.hue, hsl.saturation, hsl.luminance);  
  292.   
  293.   
  294.   
  295.   
  296.   
  297.     getchar();  
  298.   
  299.     return  0;  
  300.   
  301. }  
  302.   
  303.   
  304.   
  305. // 在Windows系统下,HSL分量的范围是[0,240]。参考“画笔”程序,可以看到RGB(红|绿|蓝)   
  306.   
  307. // 和HSL(色调|饱和度|亮度)的联系。   
  308.   
  309. // 下面的代码,把COLOR_HSL的分量值变为Windows的HSL分量,取值在[0,240]之间,需要:   
  310.   
  311.   
  312.   
  313. COLOR_HSL  hsl={300, 50, 82};  
  314.   
  315.   
  316.   
  317. // 下面为COLOR_HSL到Windows的HSL的转换:   
  318.   
  319. win_H = 240 * hsl.hue / 360.f;  
  320.   
  321. win_S = 240 * hsl.saturation / 100.f;  
  322.   
  323. win_L = 240 * hsl.luminance / 100.f; 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值