|
-
April 9th, 1999, 02:21 PM
#1
Lum from RGB?
Does anyone know if there's a formula for calculating a color's luminosity from its RGB values?
-
April 9th, 1999, 06:31 PM
#2
Re: Lum from RGB?
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
#3
Re: Lum from RGB?
Thanks; what you supplied was extremely helpful.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|