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