VBspeed / Colors / HSLToRGB
VBspeed © 2000-10, updated: 24-Nov-2001
HSLToRGB HSL to RGB, Formula 1
See also HSLToRGB2


Function HSLToRGB
Converts from the HSL to the RGB color model, more specifically converts Hue, Saturation, and Luminance values to Red, Green, and Blue values. It's the inverse of RGBToHSL.
More on HSL and RGB here.
I propose the following definition:
    Function HSLToRGB( _
        ByVal Hue As Long, _
        ByVal Saturation As Long, _
        ByVal Luminance As Long, _
        Optional Validate As Boolean _
      ) As Long
While the inverse function RGBToHSL returns a Type HSL, I believe it's more practical to handle the incoming HSL parameters individually. Might be a matter of taste, though.
The optional Validate parameter is a switch to an input check routine, which I think you want to have here in real life. However, it will not be timed below (all calls have Validate=False) because Validation of off-topic. Here is the one I use at home: ValidateHSL.
Use these functions (VB5/6-compatible) to verify the correctness of your Formula 1 code and your Formula 2 code.
Code
HSLToRGB01
Public Function HSLToRGB01( _
    ByVal Hue As Long, _
    ByVal Saturation As Long, _
    ByVal Luminance As Long, _
    Optional Validate As Boolean _
  ) As Long
' by Branco Medeiros, 1999, branco@apis.com.br
'   (adapted from Java.awt.Color.java)
' adjusted to our definition by Donald, 20011119
  Dim R As Long, G As Long, B As Long
  Dim nH As Single, nS As Single, nL As Single
  Dim nF As Single, nP As Single, nQ As Single, nT As Single
  Dim lH As Long
  
  If Validate Then ValidateHSL Hue, Saturation, Luminance
  
  If Saturation > 0 Then
  
    nH = Hue / 60: nL = Luminance / 100: nS = Saturation / 100
    
    lH = Int(nH)
    nF = nH - lH
    nP = nL * (1 - nS)
    nQ = nL * (1 - nS * nF)
    nT = nL * (1 - nS * (1 - nF))
    Select Case lH
    Case 0
      R = nL * 255
      G = nT * 255
      B = nP * 255
    Case 1
      R = nQ * 255
      G = nL * 255
      B = nP * 255
    Case 2
      R = nP * 255
      G = nL * 255
      B = nT * 255
    Case 3
      R = nP * 255
      G = nQ * 255
      B = nL * 255
    Case 4
      R = nT * 255
      G = nP * 255
      B = nL * 255
    Case 5
      R = nL * 255
      G = nP * 255
      B = nQ * 255
    End Select
  Else
    R = (Luminance * 255) / 100
    G = R: B = R
  End If
  
  HSLToRGB01 = RGBToLongSafe(R, G, B)
  
End Function

Private Function RGBToLongSafe(ByVal R&, ByVal G&, ByVal B&) As Long ' This function is just a wrap around the built in RGB function Call xLimit(R, 0, 255) Call xLimit(G, 0, 255) Call xLimit(B, 0, 255) RGBToLongSafe = RGB(R, G, B) End Function
Private Function xLimit(Value As Long, Lower As Long, Higher As Long) As Long ' Auxiliary procedure to limit (!) a given value to a specified range If Value < Lower Then Value = Lower If Value > Higher Then Value = Higher xLimit = Value End Function
HSLToRGB02
Public Function HSLToRGB02( _
    ByVal Hue As Long, _
    ByVal Saturation As Long, _
    ByVal Luminance As Long, _
    Optional Validate As Boolean _
  ) As Long
' by Donald (Sterex 1996), donald@xbeat.net, 20011119
  Dim R As Long, G As Long, B As Long
  Dim lMax As Long, lMid As Long, lMin As Long
  Dim q As Single

  If Validate Then ValidateHSL Hue, Saturation, Luminance

  lMax = (Luminance * 255) / 100
  lMin = (100 - Saturation) * lMax / 100
  q = (lMax - lMin) / 60
  
  Select Case Hue
  Case 0 To 60
    lMid = (Hue - 0) * q + lMin
    R = lMax: G = lMid: B = lMin
  Case 60 To 120
    lMid = -(Hue - 120) * q + lMin
    R = lMid: G = lMax: B = lMin
  Case 120 To 180
    lMid = (Hue - 120) * q + lMin
    R = lMin: G = lMax: B = lMid
  Case 180 To 240
    lMid = -(Hue - 240) * q + lMin
    R = lMin: G = lMid: B = lMax
  Case 240 To 300
    lMid = (Hue - 240) * q + lMin
    R = lMid: G = lMin: B = lMax
  Case 300 To 360
    lMid = -(Hue - 360) * q + lMin
    R = lMax: G = lMin: B = lMid
  End Select
  
  HSLToRGB02 = B * &H10000 + G * &H100& + R

End Function
HSLToRGB03
Public Function HSLToRGB03( _
    ByVal Hue As Long, _
    ByVal Saturation As Long, _
    ByVal Luminance As Long, _
    Optional Validate As Boolean _
  ) As Long
' by Donald (Sterex 1996), donald@xbeat.net, 20011124
  Dim R As Long, G As Long, b As Long
  Dim lMax As Long, lMid As Long, lMin As Long
  Dim q As Single

  If Validate Then ValidateHSL Hue, Saturation, Luminance

  lMax = (Luminance * 255) / 100
  
  If Saturation > 0 Then
    
    lMin = (100 - Saturation) * lMax / 100
    q = (lMax - lMin) / 60
    
    Select Case Hue
    Case 0 To 60
      lMid = (Hue - 0) * q + lMin
      R = lMax: G = lMid: b = lMin
    Case 60 To 120
      lMid = -(Hue - 120) * q + lMin
      R = lMid: G = lMax: b = lMin
    Case 120 To 180
      lMid = (Hue - 120) * q + lMin
      R = lMin: G = lMax: b = lMid
    Case 180 To 240
      lMid = -(Hue - 240) * q + lMin
      R = lMin: G = lMid: b = lMax
    Case 240 To 300
      lMid = (Hue - 240) * q + lMin
      R = lMid: G = lMin: b = lMax
    Case 300 To 360
      lMid = -(Hue - 360) * q + lMin
      R = lMax: G = lMin: b = lMid
    End Select
  
    HSLToRGB03 = b * &H10000 + G * &H100& + R
  
  Else
    
    HSLToRGB03 = lMax * &H10101

  End If

End Function
Calls
1Hue = 75: Saturation = 50: Luminance = 25
2Hue = 235: Saturation = 93: Luminance = 72
3Hue = 0: Saturation = 50: Luminance = 25
4Hue = 75: Saturation = 0: Luminance = 25
5Hue = 75: Saturation = 50: Luminance = 0
Charts
 VB5 Charts
CodeAuthorDopingNotes
HSLToRGB01 Branco  
HSLToRGB02 Donald  
HSLToRGB03 Donald  
Call 1
31.541.295µs
11.000.843µs
21.010.849µs
Call 2
31.401.180µs
11.000.843µs
21.050.883µs
Call 3
21.660.554µs
32.280.760µs
11.000.334µs
Call 4
32.041.211µs
11.000.593µs
21.010.598µs
 VB6 Charts
CodeAuthorDopingNotes
HSLToRGB01 Branco  
HSLToRGB02 Donald  
HSLToRGB03 Donald  
Call 1
31.541.381µs
11.000.898µs
21.010.906µs
Call 2
31.431.277µs
21.020.909µs
11.000.892µs
Call 3
21.810.601µs
32.450.814µs
11.000.332µs
Call 4
32.001.297µs
11.000.648µs
21.010.656µs
Notes & Conclusions
Concerning VB6/Call 2: HSLToRGB03 should not be faster than HSLToRGB02, of course. Some things remain unexplained. Particularly when they last shorter than 1 micro-second. Live fast, die young, don't ask questions.
Got comments? How to read all those numbers

top




VBspeed © 2000-10 by Donald Lessau