April 9th, 1999, 02:21 PM
Does anyone know if there's a formula for calculating a color's luminosity from its RGB values?
|
Click to See Complete Forum and Search --> : Lum from RGB? April 9th, 1999, 02:21 PM Does anyone know if there's a formula for calculating a color's luminosity from its RGB values? LALeonard April 9th, 1999, 06:31 PM Try this: ///////////////////////////////////////////////////////////////////////////// // Conversion routines: RGB to HLS (Red-Green-Blue to Hue-Luminosity-Saturation). // See Microsoft KnowledgeBase article Q29240. #define HLSMAX 240 // 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 (255). #define UNDEFINED (HLSMAX * 2 / 3) // Hue is undefined if Saturation is 0 // (grey-scale). This value determines // where the Hue scrollbar is initially // set for achromatic colors. // Convert RGB to HLS. /* static */ void Generic::RGBtoHLS(COLORREF crRGB, WORD& wH, WORD& wL, WORD& wS) { // Get R, G, and B out of COLORREF. WORD wR(GetRValue(crRGB)); WORD wG(GetGValue(crRGB)); WORD wB(GetBValue(crRGB)); // Calculate "lightness". BYTE byMax(static_cast<BYTE> (max(max(wR, wG), wB))); BYTE byMin(static_cast<BYTE> (min(min(wR, wG), wB))); wL = static_cast<WORD> ((((byMax + byMin) * HLSMAX) + RGBMAX) / (2 * RGBMAX)); // r=g=b --> achromatic case. if (byMax == byMin) { wS = 0; wH = UNDEFINED; } else { // Chromatic case. // Saturation. if (wL <= (HLSMAX / 2)) { wS = static_cast<WORD> ((((byMax - byMin) * HLSMAX) + ((byMax+byMin) / 2)) / (byMax + byMin)); } else { wS = static_cast<WORD> ((((byMax - byMin) * HLSMAX) + ((2 * RGBMAX - byMax - byMin) / 2)) / (2 * RGBMAX - byMax - byMin)); } // Hue. WORD wRdelta(static_cast<WORD> ((((byMax - wR) * (HLSMAX / 6)) + ((byMax - byMin) / 2)) / (byMax - byMin))); WORD wGdelta(static_cast<WORD> ((((byMax - wG) * (HLSMAX / 6)) + ((byMax - byMin) / 2)) / (byMax - byMin))); WORD wBdelta(static_cast<WORD> ((((byMax - wB) * (HLSMAX / 6)) + ((byMax - byMin) / 2)) / (byMax - byMin))); if (wR == byMax) { wH = static_cast<WORD> (wBdelta - wGdelta); } else if (wG == byMax) { wH = static_cast<WORD> ((HLSMAX / 3) + wRdelta - wBdelta); } else { // B == byMax wH = static_cast<WORD> (((2 * HLSMAX) / 3) + wGdelta - wRdelta); } if (wH < 0) { wH += HLSMAX; } if (wH > HLSMAX) { wH -= HLSMAX; } } } // Convert HLS to RGB. /* static */ COLORREF Generic::HLStoRGB(WORD wH, WORD wL, WORD wS) { WORD wR(0); WORD wG(0); WORD wB(0); // Achromatic case. if (0 == wS) { wR = static_cast<WORD> ((wL * RGBMAX) / HLSMAX); wG = static_cast<WORD> ((wL * RGBMAX) / HLSMAX); wB = static_cast<WORD> ((wL * RGBMAX) / HLSMAX); if (UNDEFINED != wH) { _ASSERTE(! "ERROR"); } } else { // Chromatic case. WORD Magic1(0); WORD Magic2(0); // Set up magic numbers. if (wL <= HLSMAX / 2) { Magic2 = static_cast<WORD> ((wL * (HLSMAX + wS) + (HLSMAX / 2)) / HLSMAX); } else { Magic2 = static_cast<WORD> (wL + wS - ((wL * wS) + (HLSMAX / 2)) / HLSMAX); } Magic1 = static_cast<WORD> (2 * wL - Magic2); // Get RGB, change units from HLSMAX to RGBMAX. wR = static_cast<WORD> ((HueToRGB(Magic1, Magic2, static_cast<WORD> (wH + (HLSMAX / static_cast<WORD> (3)))) * RGBMAX + (HLSMAX / static_cast<WORD> (2))) / HLSMAX); wG = static_cast<WORD> ((HueToRGB(Magic1, Magic2, static_cast<WORD> (wH)) * RGBMAX + (HLSMAX / static_cast<WORD> (2))) / HLSMAX); wB = static_cast<WORD> ((HueToRGB(Magic1, Magic2, static_cast<WORD> (wH - (HLSMAX / static_cast<WORD> (3)))) * RGBMAX + (HLSMAX / static_cast<WORD> (2))) / HLSMAX); } return RGB(wR,wG,wB); } // Utility routine for HLStoRGB. /* static */ WORD Generic::HueToRGB(WORD w1, WORD w2, WORD wH) { // Range check: note values passed add/subtract thirds of range. if (wH < 0) { wH += HLSMAX; } if (wH > HLSMAX) { wH -= HLSMAX; } // Return r, g, or b value from this tridrant. if (wH < HLSMAX / 6) { return static_cast<WORD> (w1 + (((w2 - w1) * wH + (HLSMAX / 12)) / (HLSMAX / 6))); } if (wH < HLSMAX / 2) { return w2; } if (wH < (HLSMAX * 2) / 3) { return static_cast<WORD> (w1 + (((w2 - w1) * (((HLSMAX * 2) / 3) - wH) + (HLSMAX / 12)) / (HLSMAX / 6))); } else { return w1; } } LA Leonard - Definitive Solutions, Inc. April 11th, 1999, 07:54 AM Thanks; what you supplied was extremely helpful. codeguru.com
Copyright Internet.com Inc., All Rights Reserved. |