#pragma once</p><p>#include <shlwapi.h><br />#pragma comment(lib, "shlwapi.lib")</p><p>class CColor_RGB_HLS<br />{<br /> #define HLSMAX 240 /* H,L, and S vary over 0-HLSMAX */<br /> #define RGBMAX 255 /* R,G, and B vary over 0-RGBMAX */<br /> /* HLSMAX BEST IF DIVISIBLE BY 6 */<br /> /* RGBMAX, HLSMAX must each fit in a byte. */ </p><p> /* Hue is undefined if Saturation is 0 (grey-scale) */<br /> /* This value determines where the Hue scrollbar is */<br /> /* initially set for achromatic colors */<br /> #define UNDEFINED (HLSMAX*2/3)</p><p> /* utility routine for HLStoRGB */<br /> INT HueToRGB(INT n1,INT n2,INT hue)<br /> {<br /> /* range check: note values passed add/subtract thirds of range */<br /> if (hue < 0)<br /> hue += HLSMAX;</p><p> if (hue > HLSMAX)<br /> hue -= HLSMAX;</p><p> /* return r,g, or b value from this tridrant */<br /> if (hue < (HLSMAX/6))<br /> return ( n1 + (((n2-n1)*hue+(HLSMAX/12))/(HLSMAX/6)) );<br /> if (hue < (HLSMAX/2))<br /> return ( n2 );<br /> if (hue < ((HLSMAX*2)/3))<br /> return ( n1 + (((n2-n1)*(((HLSMAX*2)/3)-hue)+(HLSMAX/12))/(HLSMAX/6)) );<br /> else<br /> return ( n1 );<br /> }</p><p>public:<br /> WORD GetHLSMax() { return HLSMAX; }<br /> typedef struct _COLOR_HLS<br /> {<br /> WORD H;<br /> union<br /> {<br /> WORD L;<br /> WORD B;<br /> };<br /> WORD S;<br /> }COLOR_HLS, COLOR_HBS;</p><p>#if _MSC_VER > 1400<br /> COLOR_HLS ColorRGBToHLS(const COLORREF lRGBColor)<br /> {<br /> WORD H, L, S;<br /> ::ColorRGBToHLS(lRGBColor, &H, &L, &S);<br /> COLOR_HLS mHLS={H, L, S};<br /> return mHLS;<br /> }</p><p> COLORREF ColorHLSToRGB(COLOR_HLS mHLS)<br /> {<br /> return ::ColorHLSToRGB(mHLS.H, mHLS.L, mHLS.S);<br /> }<br />#endif</p><p> virtual COLOR_HLS _ColorRGBToHLS(BYTE R, BYTE G, BYTE B) //* input RGB values */<br /> {<br /> BYTE cMax,cMin; /* max and min RGB values */<br /> WORD Rdelta,Gdelta,Bdelta; /* intermediate value: % of spread from max*/<br /> INT H,L,S;</p><p> /* calculate lightness */<br /> cMax = max( max(R,G), B);<br /> cMin = min( min(R,G), B);<br /> L = ( ((cMax+cMin)*HLSMAX) + RGBMAX )/(2*RGBMAX);</p><p> if (cMax == cMin) /* r=g=b --> achromatic case */<br /> {<br /> S = 0; /* saturation */<br /> H = UNDEFINED; /* hue */<br /> }<br /> else /* chromatic case */<br /> {<br /> /* saturation */<br /> if (L <= (HLSMAX/2))<br /> S = ( ((cMax-cMin)*HLSMAX) + ((cMax+cMin)/2) ) / (cMax+cMin);<br /> else<br /> S = ( ((cMax-cMin)*HLSMAX) + ((2*RGBMAX-cMax-cMin)/2) )<br /> / (2*RGBMAX-cMax-cMin);</p><p> /* hue */<br /> Rdelta = ( ((cMax-R)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin);<br /> Gdelta = ( ((cMax-G)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin);<br /> Bdelta = ( ((cMax-B)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin);</p><p> if (R == cMax)<br /> H = Bdelta - Gdelta;<br /> else if (G == cMax)<br /> H = (HLSMAX/3) + Rdelta - Bdelta;<br /> else /* B == cMax */<br /> H = ((2*HLSMAX)/3) + Gdelta - Rdelta;</p><p> if (H < 0)<br /> H += HLSMAX;<br /> if (H > HLSMAX)<br /> H -= HLSMAX;<br /> }</p><p> COLOR_HLS mHLS={H, L, S};<br /> return mHLS;<br /> }</p><p> virtual COLOR_HLS _ColorRGBToHLS(COLORREF lRGBColor) //<br /> {<br /> return _ColorRGBToHLS(GetRValue(lRGBColor), GetGValue(lRGBColor), GetBValue(lRGBColor));<br /> }</p><p> virtual COLORREF _ColorHLSToRGB(WORD hue, WORD lum, WORD sat)<br /> {<br /> WORD R,G,B; /* RGB component values */<br /> INT Magic1,Magic2; /* calculated magic numbers (really!) */ </p><p> if (sat == 0) /* achromatic case */<br /> {<br /> R=G=B=(lum*RGBMAX)/HLSMAX;<br /> if (hue != UNDEFINED)<br /> {<br /> /* ERROR */<br /> }<br /> }<br /> else /* chromatic case */<br /> {<br /> /* set up magic numbers */<br /> if (lum <= (HLSMAX/2))<br /> Magic2 = (lum*(HLSMAX + sat) + (HLSMAX/2))/HLSMAX;<br /> else<br /> Magic2 = lum + sat - ((lum*sat) + (HLSMAX/2))/HLSMAX;<br /> Magic1 = 2*lum-Magic2;</p><p> /* get RGB, change units from HLSMAX to RGBMAX */<br /> R = (HueToRGB(Magic1,Magic2,hue+(HLSMAX/3))*RGBMAX + (HLSMAX/2))/HLSMAX;<br /> G = (HueToRGB(Magic1,Magic2,hue)*RGBMAX + (HLSMAX/2)) / HLSMAX;<br /> B = (HueToRGB(Magic1,Magic2,hue-(HLSMAX/3))*RGBMAX + (HLSMAX/2))/HLSMAX;<br /> }<br /> return(RGB(R,G,B));<br /> }</p><p> virtual COLORREF _ColorHLSToRGB(const COLOR_HLS mHLS)<br /> {<br /> return _ColorHLSToRGB( mHLS.H, mHLS.L, mHLS.S);<br /> }<br />};</p><p>
//測試代碼<br /> CColor_RGB_HLS mConv;<br /> COLORREF mRGB = RGB(200, 0, 0);<br /> CColor_RGB_HLS::_COLOR_HLS mHLS = mConv._ColorRGBToHLS(mRGB);<br /> mHLS.L = min(mConv.GetHLSMax(), mHLS.L + 30);<br /> mRGB = mConv._ColorHLSToRGB(mHLS);