VBspeed / Colors / RGBToHSL VBspeed © 2000-10, updated: 21-Nov-2001 RGBToHSL RGB to HSL, Formula 1 See also RGBToHSL2

 Function RGBToHSL Converts from the RGB to the HSL color model, more specifically converts Red, Green, and Blue values to Hue, Saturation, and Luminance values. It's the inverse of HSLToRGB. Hue is interpreted as an angle in the color circle (0-360 degree, where 0°=360°). Red is positioned at 0°, green at 120°, and blue at 240°. Saturation is a measure of the "purity" of a hue (0 to 100%). As saturation is decreased, the hue becomes more gray. A saturation value of zero results in a grayscale value. Luminance (aka Lightness, Brightness) is the amount of black or white in a color (0 to 100%). Increasing lightness adds white to the hue. Decreasing lightness adds black to the hue. The Formulas: conversion math between RGB and HSL comes in various dialects. Sometimes Red is positioned at 60°, sometimes Luminance and Saturation are calculated quite differently. Shown below are the two main schemes. If you actually do image editing via HSL you will probably find the version 2 approach superior (look at how Luminance is arrived at in version 1 - not such a brilliant concept of "Luminance"). ``` lMax = Maximum(R, G, B): lMin = Minimum(R, G, B) Formula 1 - RGBToHSL and HSLToRGB: Luminance = 100 * lMax / 255 Saturation = 100 * ((lMax - lMin) / lMax) Formula 2 - RGBToHSL2 and HSLToRGB2: Luminance = 100 * (lMax + lMin) / 510 If Luminance <= 50 Then Saturation = 100 * (lMax - lMin) / (lMax + lMin) Else Saturation = 100 * (lMax - lMin) / (510 - (lMax + lMin)) End If ``` The HSL model covers a total of 360 x 101 x 101 = 3,672,360 definable colors, much less (ca 4.5 times) than the 16,777,216 defined in the RGB space. The number of actually different colors is even smaller, for example all colors with Luminance=0 are perfect black (RGB 0,0,0). Because of the differences between the two color models, converting between RGB and HSB values is not a transitive operation, that is, given an RGB value converted to HSB, when converting back to RGB the result may be different from the original. And vice-versa. :: More color model infos :: Watch HSL in action It's practical to define a Type to hold HSL. The definition then looks like this: ``` Type HSL Hue As Long Saturation As Long Luminance As Long End Type Function RGBToHSL(ByVal RGBValue As Long) As HSL ``` Of course one could easily stuff HSL into a smaller structure (Integer+Byte+Byte), but Longs work faster and are more tolerant. Use these functions (VB5/6-compatible) to verify the correctness of your Formula 1 code and your Formula 2 code. Since all color models are physio/psychologically defined, minimal differences are allowed and should not discourage you. Color is a product of your mind. (Some people say everything is.)(I mean: *think* everything is.)
 Code RGBToHSL01 ```Public Function RGBToHSL01(ByVal RGBValue As Long) As HSL ' by Branco Medeiros, 1999, branco@apis.com.br ' (adapted from Java.awt.Color.java) ' adjusted to our definition by Donald, 20011116 Dim lMin As Long, lMax As Long, lDelta As Long Dim R As Long, G As Long, B As Long Dim nTemp As Single R = RGBValue And &HFF G = (RGBValue And &HFF00&) \ &H100& B = (RGBValue And &HFF0000) \ &H10000 lMax = IIf(R > G, IIf(R > B, R, B), IIf(G > B, G, B)) lMin = IIf(R < G, IIf(R < B, R, B), IIf(G < B, G, B)) RGBToHSL01.Luminance = (lMax * 100) / 255 If lMax > 0 Then lDelta = lMax - lMin RGBToHSL01.Saturation = (lDelta / lMax) * 100 If lDelta > 0 Then If lMax = R Then nTemp = (G - B) / lDelta ElseIf lMax = G Then nTemp = 2 + (B - R) / lDelta Else nTemp = 4 + (R - G) / lDelta End If RGBToHSL01.Hue = nTemp * 60 If RGBToHSL01.Hue < 0 Then RGBToHSL01.Hue = RGBToHSL01.Hue + 360 End If End If End If End Function ``` RGBToHSL02 ```Public Function RGBToHSL02(ByVal RGBValue As Long) As HSL ' by Donald (Sterex 1996), donald@xbeat.net, 20011116 Dim R As Long, G As Long, B As Long Dim lMax As Long, lMin As Long Dim q As Single R = RGBValue And &HFF G = (RGBValue And &HFF00&) \ &H100& B = (RGBValue And &HFF0000) \ &H10000 If R > G Then lMax = R: lMin = G Else lMax = G: lMin = R End If If B > lMax Then lMax = B ElseIf B < lMin Then lMin = B End If RGBToHSL02.Luminance = lMax * 100 / 255 If lMax > lMin Then RGBToHSL02.Saturation = (lMax - lMin) * 100 / lMax q = 60 / (lMax - lMin) Select Case lMax Case R If B > G Then RGBToHSL02.Hue = q * (G - B) + 360 Else RGBToHSL02.Hue = q * (G - B) End If Case G RGBToHSL02.Hue = q * (B - R) + 120 Case B RGBToHSL02.Hue = q * (R - G) + 240 End Select End If End Function ``` RGBToHSL03 ```Public Function RGBToHSL03(ByVal RGBValue As Long) As HSL ' by Paul - wpsjr1@syix.com, 20011120 Dim R As Long, G As Long, B As Long Dim lMax As Long, lMin As Long Dim q As Single Dim lDifference As Long Static Lum(255) As Long Static QTab(255) As Single Static init As Long If init = 0 Then For init = 2 To 255 ' 0 and 1 are both 0 Lum(init) = init * 100 / 255 Next For init = 1 To 255 QTab(init) = 60 / init Next init End If R = RGBValue And &HFF G = (RGBValue And &HFF00&) \ &H100& B = (RGBValue And &HFF0000) \ &H10000 If R > G Then lMax = R: lMin = G Else lMax = G: lMin = R End If If B > lMax Then lMax = B ElseIf B < lMin Then lMin = B End If RGBToHSL03.Luminance = Lum(lMax) lDifference = lMax - lMin If lDifference Then ' do a 65K 2D lookup table here for more speed if needed RGBToHSL03.Saturation = (lDifference) * 100 / lMax q = QTab(lDifference) Select Case lMax Case R If B > G Then RGBToHSL03.Hue = q * (G - B) + 360 Else RGBToHSL03.Hue = q * (G - B) End If Case G RGBToHSL03.Hue = q * (B - R) + 120 Case B RGBToHSL03.Hue = q * (R - G) + 240 End Select End If End Function ``` Calls 1 RGBValue = &HE61C94 2 RGBValue = &H1CE694 3 RGBValue = &H1C1C1C 4 RGBValue = &H0& Charts
VB5 Charts
 Code Author Doping Notes RGBtoHSL01 Branco RGBtoHSL02 Donald RGBtoHSL03 Paul
 Call 1 3 11.57 7.834µs 2 1.49 1.007µs 1 1.00 0.677µs
 Call 2 3 11.73 7.828µs 2 1.51 1.005µs 1 1.00 0.667µs
 Call 3 3 29.05 7.473µs 2 1.89 0.486µs 1 1.00 0.257µs
 Call 4 3 28.23 7.278µs 2 1.56 0.403µs 1 1.00 0.258µs
VB6 Charts
 Code Author Doping Notes RGBtoHSL01 Branco RGBtoHSL02 Donald RGBtoHSL03 Paul
 Call 1 3 13.05 9.015µs 2 1.52 1.047µs 1 1.00 0.691µs
 Call 2 3 12.84 9.013µs 2 1.44 1.013µs 1 1.00 0.702µs
 Call 3 3 33.16 8.660µs 2 1.89 0.493µs 1 1.00 0.261µs
 Call 4 3 32.20 8.395µs 2 1.57 0.410µs 1 1.00 0.261µs
 Notes & Conclusions RGBToHSL01 has a severe problem, and the name of it is "IIf" aka "TWVBFEW" (the worst VB function ever written). But that's another story. RGBToHSL03 demonstrates the power of LUTs (Look Up Tables). Got comments? top

VBspeed © 2000-10 by Donald Lessau