B4A Library HSL to RGB function (get a color in a rainbow)

This is the perfect example of how useful B4A is for VB programmers
I took some VB code for getting a color out of a rainbow (the lower code) and converted it to B4A (the upper code) with only minor changes (the dev didn't declare his variables properly for the most part)
You can compare to see just how little work I did to convert it

B4X:
Sub HSLtoRGB(Hue As Int, Saturation As Int, Luminance As Int, Alpha As Int ) As Int 
   Dim temp3(3) As Double , Red As Int, Green As Int, Blue As Int ,temp1 As Double, temp2 As Double ,n As Int 
   Dim pHue As Double, pSat As Double, pLum As Double , pRed As Double, pGreen As Double, pBlue As Double 
   
   pHue = Min(239, Hue) / 239
   pSat = Min(239, Saturation) / 239
   pLum = Min(239, Luminance) / 239

   If pSat = 0 Then
      pRed = pLum
      pGreen = pLum
      pBlue = pLum
   Else
      If pLum < 0.5 Then
         temp2 = pLum * (1 + pSat)
      Else
         temp2 = pLum + pSat - pLum * pSat
      End If
      temp1 = 2 * pLum - temp2
   
      temp3(0) = pHue + 1 / 3
      temp3(1) = pHue
      temp3(2) = pHue - 1 / 3
      
      For n = 0 To 2
         If temp3(n) < 0 Then temp3(n) = temp3(n) + 1
         If temp3(n) > 1 Then temp3(n) = temp3(n) - 1
      
         If 6 * temp3(n) < 1 Then
            temp3(n) = temp1 + (temp2 - temp1) * 6 * temp3(n)
         Else
            If 2 * temp3(n) < 1 Then
               temp3(n) = temp2
            Else
               If 3 * temp3(n) < 2 Then
                  temp3(n) = temp1 + (temp2 - temp1) * ((2 / 3) - temp3(n)) * 6
               Else
                  temp3(n) = temp1
                End If
             End If
          End If
       Next 

       pRed = temp3(0)
       pGreen = temp3(1)
       pBlue = temp3(2)
    End If

    Red = pRed * 255
    Green = pGreen * 255
    Blue = pBlue * 255

   Return Colors.ARGB(Alpha, Red,Green,Blue)
End Sub

B4X:
Public Sub HSLtoRGB(ByVal Hue As Integer, ByVal Saturation As Integer, ByVal Luminance As Integer, ByRef Red As Integer, ByRef Green As Integer, ByRef Blue As Integer)

   ReDim temp3!(0 To 2)
   
   pHue! = Hue / 239
   pSat! = Saturation / 239
   pLum! = Luminance / 239

   If pSat! = 0 Then
      pRed! = pLum!
      pGreen! = pLum!
      pBlue! = pLum!
   Else
      If pLum! < 0.5 Then
         temp2! = pLum! * (1 + pSat!)
      Else
         temp2! = pLum! + pSat! - pLum! * pSat!
      End If
      temp1! = 2 * pLum! - temp2!
   
      temp3!(0) = pHue! + 1 / 3
      temp3!(1) = pHue!
      temp3!(2) = pHue! - 1 / 3
      
      For n% = 0 To 2
         If temp3!(n%) < 0 Then temp3!(n%) = temp3!(n%) + 1
         If temp3!(n%) > 1 Then temp3!(n%) = temp3!(n%) - 1
      
         If 6 * temp3!(n%) < 1 Then
            temp3!(n%) = temp1! + (temp2! - temp1!) * 6 * temp3!(n%)
         Else
            If 2 * temp3!(n%) < 1 Then
               temp3!(n%) = temp2!
            Else
               If 3 * temp3!(n%) < 2 Then
                  temp3!(n%) = temp1! + (temp2! - temp1!) * ((2 / 3) - temp3!(n%)) * 6
               Else
                  temp3!(n%) = temp1!
                End If
             End If
          End If
       Next n%

       pRed! = temp3!(0)
       pGreen! = temp3!(1)
       pBlue! = temp3!(2)
    End If

    Red = Int(pRed! * 255)
    Green = Int(pGreen! * 255)
    Blue = Int(pBlue! * 255)

End Sub
 

naruto

Member
Licensed User
Longtime User
usage

I looked up how to use HSL on the net and wrote a small wrapper for the above provided function. Below complete source code. Note that HSL values go from 1 to 240, reason for the conversion. Color pickers on the net use a 360 degrees value for Hue and a percentage for both Sat and Lum.

By the way I would love to have a function for RGBtoHSL, anyone?

B4X:
Sub HSLtoRGB(hue As Int, Saturation As Int, Luminance As Int) As Int 
   ' Hue: 1 To 360
   ' Sat: 100% max
   ' Lum: 100% max
   
   ' online color pickers to check against
   ' http://hslpicker.com/#001eff
   ' http://www.workwithcolor.com/hsl-color-picker-01.htm
   ' or mspaint???

   Dim hue As Int = hue / 360 * 240
   Dim sat As Int =  Saturation / 100 * 240
   Dim lum As Int = Luminance / 100 * 240
   Dim RGBColor As Int = HSLtoRGB2(hue, sat, lum, 0xFF)
   
   Return RGBColor
End Sub

' http://www.b4x.com/forum/additional-libraries-classes-official-updates/18743-hsl-rgb-function-get-color-rainbow.html#post107632
Sub HSLtoRGB2(Hue As Int, Saturation As Int, Luminance As Int, Alpha As Int ) As Int 
   Dim temp3(3) As Double , Red As Int, Green As Int, Blue As Int ,temp1 As Double, temp2 As Double ,n As Int 
   Dim pHue As Double, pSat As Double, pLum As Double , pRed As Double, pGreen As Double, pBlue As Double 
   
   pHue = Min(239, Hue) / 239
   pSat = Min(239, Saturation) / 239
   pLum = Min(239, Luminance) / 239

   If pSat = 0 Then
      pRed = pLum
      pGreen = pLum
      pBlue = pLum
   Else
      If pLum < 0.5 Then
         temp2 = pLum * (1 + pSat)
      Else
         temp2 = pLum + pSat - pLum * pSat
      End If
      temp1 = 2 * pLum - temp2
   
      temp3(0) = pHue + 1 / 3
      temp3(1) = pHue
      temp3(2) = pHue - 1 / 3
      
      For n = 0 To 2
         If temp3(n) < 0 Then temp3(n) = temp3(n) + 1
         If temp3(n) > 1 Then temp3(n) = temp3(n) - 1
      
         If 6 * temp3(n) < 1 Then
            temp3(n) = temp1 + (temp2 - temp1) * 6 * temp3(n)
         Else
            If 2 * temp3(n) < 1 Then
               temp3(n) = temp2
            Else
               If 3 * temp3(n) < 2 Then
                  temp3(n) = temp1 + (temp2 - temp1) * ((2 / 3) - temp3(n)) * 6
               Else
                  temp3(n) = temp1
                End If
             End If
          End If
       Next 

       pRed = temp3(0)
       pGreen = temp3(1)
       pBlue = temp3(2)
    End If

    Red = pRed * 255
    Green = pGreen * 255
    Blue = pBlue * 255

    Return Colors.ARGB(Alpha, Red,Green,Blue)
End Sub
 

Informatix

Expert
Licensed User
Longtime User
Another method:

B4X:
Dim r As Reflector
Dim HSV(3) As Float = Array As Float(h, s, v)
Color = r.RunStaticMethod("android.graphics.Color", "HSVToColor", Array As Object(HSV), Array As String("[F"))

EDIT:
With Alpha:
B4X:
Dim r As Reflector
Dim HSV(3) As Float = Array As Float(h, s, v)
Color = r.RunStaticMethod("android.graphics.Color", "HSVToColor", Array As Object(alpha, HSV), Array As String("java.lang.int", "[F"))
 
Last edited:

naruto

Member
Licensed User
Longtime User
HSL and HSV color models

I noticed the last letter being different being a V instead of L in HSV in the post above. I looked it up in order to understand the difference, below my findings:

HSL and HSV are the two most common cylindrical-coordinate representations of points in an RGB color model.

HSL - stands for hue, saturation, and lightness (also called HLS, I think HTML CSS 3 uses this one)
HSV - stands for hue, saturation, and value (also called HSB, I think photoshop uses HSB too in the color picker)
 

Informatix

Expert
Licensed User
Longtime User
I noticed the last letter being different being a V instead of L in HSV in the post above. I looked it up in order to understand the difference, below my findings:

HSL and HSV are the two most common cylindrical-coordinate representations of points in an RGB color model.

HSL - stands for hue, saturation, and lightness (also called HLS, I think HTML CSS 3 uses this one)
HSV - stands for hue, saturation, and value (also called HSB, I think photoshop uses HSB too in the color picker)

Ah OK, I didn't pay attention to the last letter.
 

gelay

Member
Licensed User
Longtime User
Hi Informatix

Can you please help to make RGBToHsv

static void RGBToHSV(int red, int green, int blue, float[] hsv)

to work too with reflector?

Thanks
 

Informatix

Expert
Licensed User
Longtime User
Hi Informatix

Can you please help to make RGBToHsv

static void RGBToHSV(int red, int green, int blue, float[] hsv)

to work too with reflector?

Thanks

Not tried but that should work:
r.RunStaticMethod("android.graphics.Color", "RGBToHSV", Array As Object(Red, Green, Blue, HSV), Array As String("java.lang.integer", "java.lang.integer", "java.lang.integer", "[F"))

with red, green and blue as int values, and HSV an array of float
 

ydobemos

Member
Licensed User
Longtime User
Another method:
B4X:
Dim r As Reflector
Dim HSV(3) As Float = Array As Float(h, s, v)
Color = r.RunStaticMethod("android.graphics.Color", "HSVToColor", Array As Object(HSV), Array As String("[F"))

Sorry to bring up an old thread, but I'm trying to use this as a function of sorts:
B4X:
Sub HSV(H As Float, S As Float, V As Float) As ColorDrawable

Dim r As Reflector
Dim HSV(3) As Float = Array As Float(H, S, V)
HSV = r.RunStaticMethod("android.graphics.Color", "HSVToColor", Array As Object(HSV), Array As String("[F"))

End Sub

And it keeps giving this error:
B4X:
Occurred on line: 71
HSV = r.RunStaticMethod("android.graphics.Color", "HSVToColor", Array As Object(HSV), Array As String("[F"))
Word: =
But it doesn't look like there's a need for parenthesis there. Any ideas?
 

Informatix

Expert
Licensed User
Longtime User
Sorry to bring up an old thread, but I'm trying to use this as a function of sorts:
B4X:
Sub HSV(H As Float, S As Float, V As Float) As ColorDrawable

Dim r As Reflector
Dim HSV(3) As Float = Array As Float(H, S, V)
HSV = r.RunStaticMethod("android.graphics.Color", "HSVToColor", Array As Object(HSV), Array As String("[F"))

End Sub

And it keeps giving this error:
B4X:
Occurred on line: 71
HSV = r.RunStaticMethod("android.graphics.Color", "HSVToColor", Array As Object(HSV), Array As String("[F"))
Word: =
But it doesn't look like there's a need for parenthesis there. Any ideas?
You replaced Color in the code by HSV. That cannot work (HSV is an array of float, and the returned value is a color).
 

ydobemos

Member
Licensed User
Longtime User
Ah, yes, stupid mistake on my part, just copied the inside into my existing function with the same name. It works if I just leave it as "color".

However... I must be just too new at B4A, but how do I turn this code into a usable function - one what gives a color usable for views and such?
 

ydobemos

Member
Licensed User
Longtime User
I mean, if I turn it into a function, like this:
B4X:
Sub HSVtoRGB(H As Float, S As Float, V As Float) As Int '<== WHAT TYPE SHOULD THIS BE?
Dim r As Reflector
Dim HSV(3) As Float = Array As Float(H, S, V)
Result = r.RunStaticMethod("android.graphics.Color", "HSVToColor", Array As Object(HSV), Array As String("[F"))
End Sub

And make it return an Int it just shows black, thus the result is somehow improperly formatted I guess.
 

Informatix

Expert
Licensed User
Longtime User
I mean, if I turn it into a function, like this:
B4X:
Sub HSVtoRGB(H As Float, S As Float, V As Float) As Int '<== WHAT TYPE SHOULD THIS BE?
Dim r As Reflector
Dim HSV(3) As Float = Array As Float(H, S, V)
Result = r.RunStaticMethod("android.graphics.Color", "HSVToColor", Array As Object(HSV), Array As String("[F"))
End Sub

And make it return an Int it just shows black, thus the result is somehow improperly formatted I guess.
Yes the result is an Int, but you should use the code above with the Alpha setting instead. Colors in B4A are expected as ARGB colors.
 

ydobemos

Member
Licensed User
Longtime User
Thank you! It works now!

My main mistake was Having Result = instead of Return for the function part. Stupid mistake, I cannot get used to this for B4A... Sigh.
 
Top