You are currently offline, waiting for your internet to reconnect

How To Converting Colors Between RGB and HLS (HBS)

This article was previously published under Q29240
SUMMARY
The code fragment below converts colors between RGB (Red, Green,Blue) and HLS/HBS (Hue, Lightness, Saturation/Hue, Brightness,Saturation).
MORE INFORMATION
RGBtoHLS() takes a DWORD RGB value, translates it to HLS, andstores the results in the global vars H, L, and S. HLStoRGB takes thecurrent values of H, L, and S and returns the equivalent value in anRGB DWORD. The vars H, L, and S are only written to by:
  1. RGBtoHLS (initialization)
  2. The scroll bar handlers
A point of reference for the algorithms is Foley and Van Dam,"Fundamentals of Interactive Computer Graphics," Pages 618-19. Theiralgorithm is in floating point. CHART implements a less general(hardwired ranges) integral algorithm.

There are potential round-off errors throughout this sample.((0.5 + x)/y) without floating point is phrased ((x + (y/2))/y),yielding a very small round-off error. This makes many of thefollowing divisions look strange.
   */    #define  HLSMAX   RANGE /* H,L, and S vary over 0-HLSMAX */    #define  RGBMAX   255   /* R,G, and B vary over 0-RGBMAX */                            /* HLSMAX BEST IF DIVISIBLE BY 6 */                            /* RGBMAX, HLSMAX must each fit in a byte. */    /* Hue is undefined if Saturation is 0 (grey-scale) */    /* This value determines where the Hue scrollbar is */    /* initially set for achromatic colors */    #define UNDEFINED (HLSMAX*2/3)   void  RGBtoHLS(lRGBColor)   DWORD lRGBColor;   {      WORD R,G,B;          /* input RGB values */       BYTE cMax,cMin;      /* max and min RGB values */    WORD  Rdelta,Gdelta,Bdelta; /* intermediate value: % of spread from max   */       /* get R, G, and B out of DWORD */       R = GetRValue(lRGBColor);      G = GetGValue(lRGBColor);      B = GetBValue(lRGBColor);      /* calculate lightness */       cMax = max( max(R,G), B);      cMin = min( min(R,G), B);      L = ( ((cMax+cMin)*HLSMAX) + RGBMAX )/(2*RGBMAX);      if (cMax == cMin) {           /* r=g=b --> achromatic case */          S = 0;                     /* saturation */          H = UNDEFINED;             /* hue */       }      else {                        /* chromatic case */          /* saturation */          if (L <= (HLSMAX/2))            S = ( ((cMax-cMin)*HLSMAX) + ((cMax+cMin)/2) ) / (cMax+cMin);         else            S = ( ((cMax-cMin)*HLSMAX) + ((2*RGBMAX-cMax-cMin)/2) )               / (2*RGBMAX-cMax-cMin);         /* hue */       Rdelta = ( ((cMax-R)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin);      Gdelta = ( ((cMax-G)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin);      Bdelta = ( ((cMax-B)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin);         if (R == cMax)            H = Bdelta - Gdelta;         else if (G == cMax)            H = (HLSMAX/3) + Rdelta - Bdelta;         else /* B == cMax */             H = ((2*HLSMAX)/3) + Gdelta - Rdelta;         if (H < 0)            H += HLSMAX;         if (H > HLSMAX)            H -= HLSMAX;      }   }   /* utility routine for HLStoRGB */    WORD HueToRGB(n1,n2,hue)   WORD n1;   WORD n2;   WORD hue;   {      /* range check: note values passed add/subtract thirds of range */       if (hue < 0)         hue += HLSMAX;       if (hue > HLSMAX)         hue -= HLSMAX;      /* return r,g, or b value from this tridrant */       if (hue < (HLSMAX/6))          return ( n1 + (((n2-n1)*hue+(HLSMAX/12))/(HLSMAX/6)) );      if (hue < (HLSMAX/2))         return ( n2 );      if (hue < ((HLSMAX*2)/3))         return ( n1 +    (((n2-n1)*(((HLSMAX*2)/3)-hue)+(HLSMAX/12))/(HLSMAX/6))   );      else         return ( n1 );   }   DWORD HLStoRGB(hue,lum,sat)   WORD hue;   WORD lum;   WORD sat;    {       WORD R,G,B;                /* RGB component values */       WORD  Magic1,Magic2;       /* calculated magic numbers (really!) */       if (sat == 0) {            /* achromatic case */          R=G=B=(lum*RGBMAX)/HLSMAX;         if (hue != UNDEFINED) {            /* ERROR */           }       }      else  {                    /* chromatic case */          /* set up magic numbers */          if (lum <= (HLSMAX/2))            Magic2 = (lum*(HLSMAX + sat) + (HLSMAX/2))/HLSMAX;         else            Magic2 = lum + sat - ((lum*sat) + (HLSMAX/2))/HLSMAX;         Magic1 = 2*lum-Magic2;         /* get RGB, change units from HLSMAX to RGBMAX */          R = (HueToRGB(Magic1,Magic2,hue+(HLSMAX/3))*RGBMAX +   (HLSMAX/2))/HLSMAX;         G = (HueToRGB(Magic1,Magic2,hue)*RGBMAX + (HLSMAX/2)) / HLSMAX;         B = (HueToRGB(Magic1,Magic2,hue-(HLSMAX/3))*RGBMAX +   (HLSMAX/2))/HLSMAX;      }      return(RGB(R,G,B));    }				
3.00 3.10 3.50 4.00 color RGB HLS HBS win16sdk
Properties

Article ID: 29240 - Last Review: 11/21/2006 15:33:13 - Revision: 3.3

Microsoft Windows Software Development Kit 3.1, Microsoft Win32 Application Programming Interface

  • kbhowto KB29240
Feedback
);m.name='ms.dqp0';m.content='true';document.getElementsByTagName('head')[0].appendChild(m);" onload="var m=document.createElement('meta');m.name='ms.dqp0';m.content='false';document.getElementsByTagName('head')[0].appendChild(m);" src="http://c1.microsoft.com/c.gif?">