Jump to content

Convert RGB to HSB


weaponx
 Share

Recommended Posts

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.2.10.0
 Author: WeaponX

 Script Function:
    Convert RGB color to HSB (like Photoshop)
 
 Converted from:
[url="http://www.oooforum.org/forum/viewtopic.phtml?t=4945"]http://www.oooforum.org/forum/viewtopic.phtml?t=4945[/url]
#ce ----------------------------------------------------------------------------

$result = _RGBtoHSB(255, 000, 000)
MsgBox(0, "Red", "H:" & $result[0] & @CRLF & "S:" & $result[1] & @CRLF & "B:" & $result[2])

$result = _RGBtoHSB(000, 255, 000)
MsgBox(0, "Green", "H:" & $result[0] & @CRLF & "S:" & $result[1] & @CRLF & "B:" & $result[2])

$result = _RGBtoHSB(000, 000, 255)
MsgBox(0, "Blue", "H:" & $result[0] & @CRLF & "S:" & $result[1] & @CRLF & "B:" & $result[2])

;Input
;$nRed 0-255
;$nGreen 0-255
;$nBlue 0-255

;Returns 3-Element array
;H:[0] 0-360
;S:[1] 0-100%
;B:[2] 0-100%

Func _RGBtoHSB($nRed, $nGreen, $nBlue)
    Local $nHue, $nSaturation, $nBrightness, $largest
    Local $hsbArray[3] = [0, 0, 0]
    
    ;Determine highest component value
    $nMax = 0
    
    If $nRed > $nMax Then $nMax = $nRed
    If $nGreen > $nMax Then $nMax = $nGreen
    If $nBlue > $nMax Then $nMax = $nBlue
    
    ;Determine lowest component value
    $nMin = 255

    If $nRed < $nMin Then $nMin = $nRed
    If $nGreen < $nMin Then $nMin = $nGreen
    If $nBlue < $nMin Then $nMin = $nBlue

    If $nMin = $nMax Then
        ;Grayscale
        $nHue = 0.0
        $nSaturation = 0.0
        $nBrightness = $nMax
    Else
        If $nRed = $nMin Then
            $d = $nGreen - $nBlue
            $h = 3.0
        ElseIf $nGreen = $nMin Then
            $d = $nBlue - $nRed
            $h = 5.0
        Else
            $d = $nRed - $nGreen
            $h = 1.0
        EndIf

        $nHue = ($h - ($d / ($nMax - $nMin))) / 6.0
        $nSaturation = ($nMax - $nMin) / $nMax
        $nBrightness = $nMax / 255.0
    EndIf

    $hsbArray[0] = $nHue * 360
    $hsbArray[1] = $nSaturation * 100
    $hsbArray[2] = $nBrightness * 100
    
    Return $hsbArray
EndFunc   ;==>_RGBtoHSB

Edited by weaponx
Link to comment
Share on other sites

Hah, nice stuff weaponx :) Interestingly, I just recently created a pair of functions to convert back and forth between RGB and HLS/HSB as well:

[sNIPPED]

These functions modify the passed array ByRef, which is ugly (I was too lazy to change it, and the behavior suited my needs when I created the function). It was a straight port form the Microsoft Knowledge Base article (KB29240) without much afterthought put into it, so it might not be as polished as it can probably be. The translation isn't perfect either (there's a bit of guesstimation going on), so there might be some discrepancies when converting back and forth and back again. The general algorithm is more-or-less there, though :)

See update in later posts...

Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Link to comment
Share on other sites

I've just updated my functions... The algorithm is exactly the same as before, but I looked at easyrgb.com's pseudocode instead to translate. This resulted in much nicer code, but more importantly, it resulted in ACCURATE conversions. At any rate, it's now formatted to UDF standard.

Global Const $_COLORCONSTANTS_HSLMAX = 240
Global Const $_COLORCONSTANTS_RGBMAX = 255

; #FUNCTION# ======================================================================================
; Name...........: _ColorConvertRGBtoHSL
; Description ...: Converts RGB to HSL
; Syntax.........: _ColorConvertRGBtoHSL($avArray)
; Parameters ....: $avArray - An array containing RGB values in their respective positions
; Return values .: Success - The array containing the HSL values for the inputted RGB values
;                  Failure - 0, sets @error to 1
; Author ........: Ultima
; Modified.......:
; Remarks .......:
; Related .......: _ColorConvertHSLtoRGB
; Link ..........; http://www.easyrgb.com/math.php?MATH=M18#text18
; Example .......;
; =================================================================================================
Func _ColorConvertRGBtoHSL($avArray)
    If UBound($avArray) <> 3 Or UBound($avArray, 0) <> 1 Then Return SetError(1, 0, 0)

    Local $nH, $nS, $nL
    Local $nR = Number($avArray[0])/$_COLORCONSTANTS_RGBMAX
    Local $nG = Number($avArray[1])/$_COLORCONSTANTS_RGBMAX
    Local $nB = Number($avArray[2])/$_COLORCONSTANTS_RGBMAX

    Local $nMax = $nR
    If $nMax < $nG Then $nMax = $nG
    If $nMax < $nB Then $nMax = $nB

    Local $nMin = $nR
    If $nMin > $nG Then $nMin = $nG
    If $nMin > $nB Then $nMin = $nB

    Local $nMinMaxSum = ($nMax + $nMin)
    Local $nMinMaxDiff = ($nMax - $nMin)

    ; Lightness
    $nL = $nMinMaxSum/2

    If $nMinMaxDiff = 0 Then
        ; Grayscale
        $nH = 0
        $nS = 0
    Else
        ; Saturation
        If $nL < 0.5 Then
            $nS = $nMinMaxDiff/$nMinMaxSum
        Else
            $nS = $nMinMaxDiff/(2 - $nMinMaxSum)
        EndIf

        ; Hue
        Switch $nMax
            Case $nR
                $nH = ($nG - $nB)/(6 * $nMinMaxDiff)
            Case $nG
                $nH = ($nB - $nR)/(6 * $nMinMaxDiff) + 1/3
            Case $nB
                $nH = ($nR - $nG)/(6 * $nMinMaxDiff) + 2/3
        EndSwitch
        If $nH < 0 Then $nH += 1
        If $nH > 1 Then $nH -= 1
    EndIf

    $avArray[0] = $nH * $_COLORCONSTANTS_HSLMAX
    $avArray[1] = $nS * $_COLORCONSTANTS_HSLMAX
    $avArray[2] = $nL * $_COLORCONSTANTS_HSLMAX

    Return $avArray
EndFunc   ;==>_ColorConvertRGBtoHSL

; #FUNCTION# ======================================================================================
; Name...........: _ColorConvertHSLtoRGB
; Description ...: Converts HSL to RGB
; Syntax.........: _ColorConvertHSLtoRGB($avArray)
; Parameters ....: $avArray - An array containing HSL values in their respective positions
; Return values .: Success - The array containing the RGB values for the inputted HSL values
;                  Failure - 0, sets @error to 1
; Author ........: Ultima
; Modified.......:
; Remarks .......:
; Related .......: _ColorConvertHSLtoRGB
; Link ..........; http://www.easyrgb.com/math.php?MATH=M19#text19
; Example .......;
; =================================================================================================
Func _ColorConvertHSLtoRGB($avArray)
    If UBound($avArray) <> 3 Or UBound($avArray, 0) <> 1 Then Return SetError(1, 0, 0)

    Local $nR, $nG, $nB
    Local $nH = Number($avArray[0])/$_COLORCONSTANTS_HSLMAX
    Local $nS = Number($avArray[1])/$_COLORCONSTANTS_HSLMAX
    Local $nL = Number($avArray[2])/$_COLORCONSTANTS_HSLMAX

    If $nS = 0 Then
        ; Grayscale
        $nR = $nL
        $nG = $nL
        $nB = $nL
    Else
        ; Chromatic
        Local $nValA, $nValB

        If $nL <= 0.5 Then
            $nValB = $nL * ($nS + 1)
        Else
            $nValB = ($nL + $nS) - ($nL * $nS)
        EndIf

        $nValA = 2 * $nL - $nValB
        $nR = __ColorConvertHueToRGB($nValA, $nValB, $nH + 1/3)
        $nG = __ColorConvertHueToRGB($nValA, $nValB, $nH)
        $nB = __ColorConvertHueToRGB($nValA, $nValB, $nH - 1/3)
    EndIf

    $avArray[0] = $nR * $_COLORCONSTANTS_RGBMAX
    $avArray[1] = $nG * $_COLORCONSTANTS_RGBMAX
    $avArray[2] = $nB * $_COLORCONSTANTS_RGBMAX

    Return $avArray
EndFunc

; #INTERNAL_USE_ONLY# =============================================================================
; Name...........: __ColorConvertHueToRGB
; Description ...: Helper function for converting HSL to RGB
; Syntax.........: __ColorConvertHueToRGB($nA, $nB, $nH)
; Parameters ....: $nA - Value A
;                  $nB - Value B
;                  $nH - Hue
; Return values .: A value based on value A and value B, dependent on the inputted hue
; Author ........: Ultima
; Modified.......:
; Remarks .......: For Internal Use Only
; Related .......:
; Link ..........; http://www.easyrgb.com/math.php?MATH=M19#text19
; Example .......;
; =================================================================================================
Func __ColorConvertHueToRGB($nA, $nB, $nH)
    If $nH < 0 Then $nH += 1
    If $nH > 1 Then $nH -= 1

    If (6 * $nH) < 1 Then Return $nA + ($nB - $nA) * 6 * $nH
    If (2 * $nH) < 1 Then Return $nB
    If (3 * $nH) < 2 Then Return $nA + ($nB - $nA) * 6 * (2/3 - $nH)
    Return $nA
EndFunc

Test code:

Local $aiInput[3] = [128, 255, 128]
$aiHSL = _ColorConvertRGBtoHSL($aiInput)
$aiRGB = _ColorConvertHSLtoRGB($aiHSL)

ConsoleWrite(StringFormat("| R: %.3f" & @TAB & "| H: %.3f" & @TAB & "| R: %.3f" & @CRLF, $aiInput[0], $aiHSL[0], $aiRGB[0]))
ConsoleWrite(StringFormat("| G: %.3f" & @TAB & "| S: %.3f" & @TAB & "| G: %.3f" & @CRLF, $aiInput[1], $aiHSL[1], $aiRGB[1]))
ConsoleWrite(StringFormat("| B: %.3f" & @TAB & "| L: %.3f" & @TAB & "| B: %.3f" & @CRLF, $aiInput[2], $aiHSL[2], $aiRGB[2]))

ConsoleWrite(@CRLF)

Local $aiInput[3] = [83, 220, 32]
$aiRGB = _ColorConvertHSLtoRGB($aiInput)
$aiHSL = _ColorConvertRGBtoHSL($aiRGB)

ConsoleWrite(StringFormat("| H: %.3f" & @TAB & "| R: %.3f" & @TAB & "| H: %.3f" & @CRLF, $aiInput[0], $aiRGB[0], $aiHSL[0]))
ConsoleWrite(StringFormat("| S: %.3f" & @TAB & "| G: %.3f" & @TAB & "| S: %.3f" & @CRLF, $aiInput[1], $aiRGB[1], $aiHSL[1]))
ConsoleWrite(StringFormat("| L: %.3f" & @TAB & "| B: %.3f" & @TAB & "| L: %.3f" & @CRLF, $aiInput[2], $aiRGB[2], $aiHSL[2]))

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Link to comment
Share on other sites

  • 3 years later...
  • 1 year later...

HSB <> HSL

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Color.au3>

; En
$LngTitle = 'Color'
$LngHue = 'Hue'
$LngSaturation = 'Saturation'
$LngLightness = 'Lightness'
$LngRed = 'Red'
$LngGreen = 'Green'
$LngBlue = 'Blue'

; Ru
; если русская локализация, то русский язык
If @OSLang = 0419 Then
$LngTitle = 'Цвет'
$LngHue = 'Тон'
$LngSaturation = 'Насыщенность'
$LngLightness = 'Светлота'
$LngRed = 'Красный'
$LngGreen = 'Зелёный'
$LngBlue = 'Синий'
EndIf

Global $HSB[3] = [40, 240, 185], $RGB[3]
$GUI = GUICreate($LngTitle, 340, 270)

$iColorLabel = GUICtrlCreateLabel('', 90, 5, 200, 30, $WS_BORDER)
$iNumLabel = GUICtrlCreateLabel('', 20, 12, 70, 17)

GUICtrlCreateGroup('HSL', 3, 45, 333, 103)
GUICtrlCreateGroup('RGB', 3, 155, 333, 103)

GUICtrlCreateLabel($LngHue, 10, 61, 80, 17)
$iValSld1 = GUICtrlCreateLabel($HSB[0], 300, 60, 30, 17)
$slider1 = GUICtrlCreateSlider(90, 55, 200, 30)
GUICtrlSetLimit(-1, 240, 0)
GUICtrlSetData(-1, $HSB[0])
$hSlider_Handle1 = GUICtrlGetHandle(-1)

GUICtrlCreateLabel($LngSaturation, 10, 91, 80, 17)
$iValSld2 = GUICtrlCreateLabel($HSB[1], 300, 90, 30, 17)
$slider2 = GUICtrlCreateSlider(90, 85, 200, 30)
GUICtrlSetLimit(-1, 240, 0)
GUICtrlSetData(-1, $HSB[1])
$hSlider_Handle2 = GUICtrlGetHandle(-1)

GUICtrlCreateLabel($LngLightness, 10, 121, 80, 17)
$iValSld3 = GUICtrlCreateLabel($HSB[2], 300, 120, 30, 17)
$slider3 = GUICtrlCreateSlider(90, 115, 200, 30)
GUICtrlSetLimit(-1, 240, 0)
GUICtrlSetData(-1, $HSB[2])
$hSlider_Handle3 = GUICtrlGetHandle(-1)

GUICtrlCreateLabel($LngRed, 10, 171, 80, 17)
$iValSldRGB1 = GUICtrlCreateLabel($HSB[0], 300, 170, 30, 17)
$sliderRGB1 = GUICtrlCreateSlider(90, 165, 200, 30)
GUICtrlSetLimit(-1, 255, 0)
GUICtrlSetData(-1, $HSB[0])
$hSlider_HandleRGB1 = GUICtrlGetHandle(-1)

GUICtrlCreateLabel($LngGreen, 10, 201, 80, 17)
$iValSldRGB2 = GUICtrlCreateLabel($HSB[1], 300, 200, 30, 17)
$sliderRGB2 = GUICtrlCreateSlider(90, 195, 200, 30)
GUICtrlSetLimit(-1, 255, 0)
GUICtrlSetData(-1, $HSB[1])
$hSlider_HandleRGB2 = GUICtrlGetHandle(-1)

GUICtrlCreateLabel($LngBlue, 10, 231, 80, 17)
$iValSldRGB3 = GUICtrlCreateLabel($HSB[2], 300, 230, 30, 17)
$sliderRGB3 = GUICtrlCreateSlider(90, 225, 200, 30)
GUICtrlSetLimit(-1, 255, 0)
GUICtrlSetData(-1, $HSB[2])
$hSlider_HandleRGB3 = GUICtrlGetHandle(-1)

_SetColorRGB()

GUISetState()
GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL")

Do
Until GUIGetMsg() = -3

Func WM_HSCROLL($hWnd, $Msg, $wParam, $lParam)
#forceref $Msg, $wParam, $lParam
Local $nScrollCode = BitAND($wParam, 0xFFFF) ; _WinAPI_LoWord
Local $value = BitShift($wParam, 16) ; _WinAPI_HiWord

If $nScrollCode = 5 Then
Switch $lParam
Case $hSlider_Handle1
GUICtrlSetData($iValSld1, $value)
$HSB[0] = $value
_SetColorRGB()
Case $hSlider_Handle2
GUICtrlSetData($iValSld2, $value)
$HSB[1] = $value
_SetColorRGB()
Case $hSlider_Handle3
GUICtrlSetData($iValSld3, $value)
$HSB[2] = $value
_SetColorRGB()
Case $hSlider_HandleRGB1
GUICtrlSetData($iValSldRGB1, $value)
$RGB[0] = $value
_SetColorHSB()
Case $hSlider_HandleRGB2
GUICtrlSetData($iValSldRGB2, $value)
$RGB[1] = $value
_SetColorHSB()
Case $hSlider_HandleRGB3
GUICtrlSetData($iValSldRGB3, $value)
$RGB[2] = $value
_SetColorHSB()
EndSwitch
EndIf

Return $GUI_RUNDEFMSG
EndFunc

Func _SetColorRGB()
$a = _ColorConvertHSLtoRGB($HSB)
For $i = 0 To 2
$RGB[$i] = Round($a[$i])
Next
$a = Hex($RGB[0], 2) & Hex($RGB[1], 2) & Hex($RGB[2], 2)
GUICtrlSetData($iNumLabel, $a)
GUICtrlSetBkColor($iColorLabel, Dec($a))

GUICtrlSetData($iValSldRGB1, $RGB[0])
GUICtrlSetData($iValSldRGB2, $RGB[1])
GUICtrlSetData($iValSldRGB3, $RGB[2])

GUICtrlSetData($sliderRGB1, $RGB[0])
GUICtrlSetData($sliderRGB2, $RGB[1])
GUICtrlSetData($sliderRGB3, $RGB[2])
EndFunc

Func _SetColorHSB()
$a = _ColorConvertRGBtoHSL($RGB)
For $i = 0 To 2
$HSB[$i] = Round($a[$i])
Next
$a = Hex($RGB[0], 2) & Hex($RGB[1], 2) & Hex($RGB[2], 2)
GUICtrlSetData($iNumLabel, $a)
GUICtrlSetBkColor($iColorLabel, Dec($a))

GUICtrlSetData($iValSld1, $HSB[0])
GUICtrlSetData($iValSld2, $HSB[1])
GUICtrlSetData($iValSld3, $HSB[2])

GUICtrlSetData($slider1, $HSB[0])
GUICtrlSetData($slider2, $HSB[1])
GUICtrlSetData($slider3, $HSB[2])
EndFunc

Photoshop uses the HSL (Ctrl + U)

Color.au3 UDF

H[0-240], S[0-240], L[0-240]

Global Const $__COLORCONSTANTS_HSLMAX = 240
;...
Local $nH = Number($avArray[0]) / $__COLORCONSTANTS_HSLMAX
Local $nS = Number($avArray[1]) / $__COLORCONSTANTS_HSLMAX
Local $nL = Number($avArray[2]) / $__COLORCONSTANTS_HSLMAX

Edit Color.au3

H[0-360], S[0-100], L[0-100]

Local $nH = Number($avArray[0]) / 360
Local $nS = Number($avArray[1]) / 100
Local $nL = Number($avArray[2]) / 100
Edited by AZJIO
Link to comment
Share on other sites

  • 2 months later...
  • 10 years later...

hey,

Recently I had to compare colors as close to human perception as possible.

I went through this topic, trying to use HSB as a colorspace rather than RGB however the results were less than pleasing.

I ended up using LAB as colorspace, while far from perfect it seemed better than HSB and RGB.

 

Func _RGB_to_lab($aRGB)
    for $i = 0 to 2
        $aRGB[$i] = $aRGB[$i]/255
        if $aRGB[$i] > 0.04045 Then
            $aRGB[$i] =(($aRGB[$i] + 0.055) / 1.055)^2.4
        Else
            $aRGB[$i] = $aRGB[$i]/12.92
        EndIf
        $aRGB[$i] = $aRGB[$i]*100
    Next
 
    Local $XYZ[3] = [0, 0, 0]
    $XYZ[0] = round($aRGB[0]*0.4124 + $aRGB[1]*0.3576 + $aRGB[2]*0.1805, 4)/95.047
    $XYZ[1] = round($aRGB[0]*0.2126 + $aRGB[1]*0.7152 + $aRGB[2]*0.0722, 4)/100.0
    $XYZ[2] = round($aRGB[0]*0.0193 + $aRGB[1]*0.1192 + $aRGB[2]*0.9505, 4)/108.883
    for $i = 0 to 2
        if $XYZ[$i] > 0.008856 Then
            $XYZ[$i] = $XYZ[$i]^0.3333333333333333
        Else
            $XYZ[$i] = ($XYZ[$i]* 7.787) + (16/116)
        EndIf
    Next
 
    Local $lab[3]= [0, 0, 0]
    $lab[0] = Round((116*$XYZ[1]) - 16 ,4)
    $lab[1] = Round((500 * ($XYZ[0] - $XYZ[1])) ,4)
    $lab[2] = Round((200 * ($XYZ[1] - $XYZ[2])) ,4)
    Return $lab
EndFunc
 
Func _compare_col($aRGB1, $aRGB2)
    Local $lab1 = _RGB_to_lab($aRGB1)
    Local $lab2 = _RGB_to_lab($aRGB2)
    Return Sqrt(($lab2[0]-$lab1[0])^2 + ($lab2[1]-$lab1[1])^2 + ($lab2[2]-$lab1[2])^2)
EndFunc

all arguments are passed around in the order : [R, G, B]

I don't know if anyone will ever use this, I did not bother much with headers nor comments, feel free to adjust as you see fit.

 

 

edit: the code was translated from a python script : https://stackoverflow.com/questions/13405956/convert-an-image-rgb-lab-with-python

who took it from an adobe cookbook site in turn.

Edited by ternal
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...