click here for a plain text version
#include-once
#include "corz_essentials.au3"
#include <misc.au3>

#cs

  corz color functions v0.4
  miscellaneous functions for manipulating colors and their values

  (c) cor + corz.org 2007->tomorrow!


    function list..

        ConvertColorValue( string{RGB hex color value}, string{output mode} [, boolean{add prefix=false} [, GUI-bool{lower-case]]})

        RGBToCMYK( string{hex rgb color[, bool{normalize to percentage}])

        RGBToHSL( string{hex rgb color)[, int{index to return}])

        RegColorToRGBHexColor()

        ; standard UDF (Color.au3) functions..
        GetColorRed($nColor)
        GetColorGreen($nColor)
        GetColorBlue($nColor)

        ColorChooser(array {Custom Colors}, HWND {Ownder})

#ce


;
; ConvertColorValue()
;
; Accepts a standard RGB hex color value, returns something else.
; This does not convert colors, it converts color *values* ..
;
; Available modes (values are case-insensitive)..
;
;        Web RGB Hex        use:    nothing (if no prefix is required), else use: "Web Hex""Web""Hex", or "w"
;        AutoIt:            use:    "Autoit RGB Hex""Autoit RGB""AutoIt Hex""AutoIt", or "a"
;        AutoIt GBR:        use:    "Autoit BGR Hex""Autoit BGR""BGR Hex", or "bgr", or "b"
;        Visual C++:        use:    "Visual C++ Hex""Visual C++ BGR""Visual C++""Visual C++ BGR Hex""C++", or "vc"
;        Delphi:            use:    "Delphi""Delphi hex", or "d"
;        RGB Integer:    use:    "RGB Integer""RGB Int""int", or "i"
;        RGB Float:        use:    "RGB Float""float", or "f"
;        Hue/Sat/Lum:    use:    "Hue/Sat/Lum""HSL", or "h"
;        CMYK:            use:    "cmyk", or "k"
;
; If no mode, or an incorrect mode is specified, ConvertColorValue() returns
; the original plain RGB hex value
;
; The third (optional) paramterer is the prefix, defaults to false.
; If set to true, the standard prefix, where applicable, is added to the
; output. eg, FF00FF becomes #FFOOFF. Currently only web hex and Delphi
; formats have a prefix. You can also use a checkbox boolean value for the
; prefix parameter. In other words, you can send a 4 for false.
;
; There is a special usage of the prefix option; if you request a CMYK value,
; and specify a prefix, you get the value "normalized", that is, re-scaled to
; percentages, which is a commonly found CMYK format.
;
; The optional fourth parameter ($index) only works when retrieving decimal
; (integer) color values ("i") You can supply the color index you wish to
; retrieve; 1=red value, 2=green value, 3=blue value.
;
; To retrieve individual HSL values, use RGBToHSL() directly (see below).
;
; ConvertColorValue() Returns a ready-to-use string (or integer, depending)
; of the required color value. Decimal, Float, CMYK, and HSL values are
; delimited by a comma, e.g. "124,90,64" (HSL: Hue:0-360,Sat:0-100,Lum: 0-100)
;
; If you want a color for use in dll calls, the Visual C++ value is the one
; you want (use "vc", or "v")
;
; The 5th parameter is Case. $ON = lower case, $OFF = UPPER CASE.
;
func ConvertColorValue($color$mode="web"$prefix=false, $index=0, $lowercase=$OFF)
    if StringLeft($color, 1) = "#" then $color = StringTrimLeft($color, 1)
    $pre = ""
    switch $mode
        ; the more long-winded options enable us to easily use human-readable names in the code
        ; utilizing the text of the menu options directly..
        case "i""RGB Integer""RGB Int""int"
            switch $index
                case 0
                    $color = Dec(StringLeft($color, 2)) & "," & Dec(StringMid($color, 3, 2)) & "," & Dec(StringRight($color, 2))
                case 1
                    return Dec(StringLeft($color, 2))
                case 2
                    return Dec(StringMid($color, 3, 2))
                case 3
                    return Dec(StringRight($color, 2))
            endswitch
        case "a""Autoit RGB Hex""Autoit RGB""AutoIt Hex""AutoIt"
            $color = '0x' & $color

        case "b""Autoit BGR Hex""Autoit BGR""BGR Hex""bgr"
            $color = '0x' & StringRight($color, 2) & StringMid($color, 3, 2) & StringLeft($color, 2)

        case "d""Delphi""Delphi Hex"
            $color = "00" & StringRight($color, 2) & StringMid($color, 3, 2) & StringLeft($color, 2)
            $pre = "$"

        case "v""vc""Visual C++ Hex""Visual C++ BGR""Visual C++""Visual C++ BGR Hex""C++"
            $color = "0x00" & StringRight($color, 2) & StringMid($color, 3, 2) & StringLeft($color, 2)

        case "RGB Float""float""f"
            $r = Round((1/255) * Dec(StringLeft($color, 2)), 2)
            $g = Round((1/255) * Dec(StringMid($color, 3, 2)), 2)
            $b = Round((1/255) * Dec(StringRight($color, 2)),2)
            $color = StringFormat("%#.2f"$r) & "," & StringFormat("%#.2f"$g) & "," & StringFormat("%#.2f"$b)

        case "h""Hue/Sat/Lum""HSL""h/s/l"
            $color = RGBToHSL($color",", 100)

        case "k""cmyk""c/m/y/k"
            if $prefix = 1 then
                $color = RGBToCMYK($color, true)
            else
                $color = RGBToCMYK($color)
            endif

        case "w""Web Hex""Web""Hex"
            $pre = "#"

    endswitch
    if not $prefix or $prefix = 4 then $pre = ""
    if $lowercase = $ON then $color = StringLower($color)
    return $pre & $color
endfunc


;
; RGBToCMYK()
;
; Very simple calculations. Basically, rgb is "additive" color, and
; CMYK is "subtractive", in other words, with CMYK, you start with
; white, and work up to black (paper) substracting brightness; and
; with rgb, you start with black, and work up to white (peecee monitor),
; adding brightness. So it's the same, but backwards. You could do it
; on your fingers.
;
; Set the optional second paramter to True get the values "normalized",
; that is, re-scaled to percentages, which is a commonly found CMYK format.
;
; Returns a comma-delimited string; "c,m,y,k", e.g. "0.761,0.08,0,0.016"
; By the way, that same value "normalized", is..    "76.1,8,0,1.6"
;
func RGBToCMYK($rgb_color$norm=0)

    ; get decimal rgb values and scale to 0-1..
    $rc_r = ConvertColorValue($rgb_color"i", 0, 1) / 255
    $rc_g = ConvertColorValue($rgb_color"i", 0, 2) / 255
    $rc_b = ConvertColorValue($rgb_color"i", 0, 3) / 255

    $k = MinMin(1-$rc_r, 1-$rc_g, 1-$rc_b)

    $c = (1 - $rc_r - $k) / ( 1 - $k)
    $m = (1 - $rc_g - $k) / ( 1 - $k)
    $y = (1 - $rc_b - $k) / ( 1 - $k)

    if $norm then
        return Round($c * 100, 1) & "," & Round($m * 100, 1) & "," & Round($y * 100, 1) & "," & Round($k * 100, 1)
    else
        return Round($c, 3) & "," & Round($m, 3) & "," & Round($y, 3) & "," & Round($k, 3)
    endif
endfunc


;
; RGBToHSL()
;
; Calculate an HSL color from an RGB color
;
; Returns a 4-element AutoIt array with element zero being the total (3)
; and the three HSL integer values..
;
;    [3, Hue (0-360 degrees), Saturation (0-1), Luminance/Lightness (0-1)]
;
; You can also specify an optional second paramter; index, being either
; 1, 2, or 3, to return ONLY Hue, Saturation, or Lightness, respectively.
;
; If you specify an index, the return value will be a single float/integer.
;
; There is also a special usage for index, which gets you back the HSL
; as a string, delimited by whatever character you set as the index value.
;
; HSL values come in all sorts of weird scales, sometimes percentages,
; sometimes 0-240, or 0-255, and others. You can deal with that at your end; or
; else feed RGBToHSL the optional third parameter, which automatically multiplies
; the Saturation and Lightness by whatever you like. 100 is common. Hue values
; are always returned in degrees, though it would be easy enough to hack that.
;
; Usage.
;
;    To retrieve the HSL as an AutoIt array..
;
;        $color_array = RGBToHSL($my_hex_color)
;
;    To retrieve the Lightness of an RGB Hex value..
;
;        $lightness = RGBToHSL($my_hex_color, 3)
;
;    To get back the HSL as a comma-delimited string..
;
;        RGBToHSL("650003"",")     [ returns:    "358,1.0,0.2" - a dark brown]
;
;
func RGBToHSL($rgb_color$idx=""$simple_array=false, $hsl_scale=1)

    $rh_r = ConvertColorValue($rgb_color"i", 0, 1) / 255
    $rh_g = ConvertColorValue($rgb_color"i", 0, 2) / 255
    $rh_b = ConvertColorValue($rgb_color"i", 0, 3) / 255

    $rh_min = MinMin($rh_r$rh_g$rh_b)
    $rh_max = MaxMax($rh_r$rh_g$rh_b)
    $rh_delta = $rh_max - $rh_min

    if $idx <> 1 then ; every little helps

        ; not perfect, this, but it's the standard method..
        $rh_lightness = ($rh_min + $rh_max) / 2
        if $idx = 3 then return Round($rh_lightness*$hsl_scale, 2)

        $rh_saturation = 0
        if $rh_lightness > 0 and $rh_lightness < 1 then
            if $rh_lightness < 0.5 then
                $rh_saturation = $rh_delta / (2 * $rh_lightness)
            else
                $rh_saturation = $rh_delta / (2 - 2 * $rh_lightness)
            endif
        endif
        if $idx = 2 then return Round($rh_saturation*$hsl_scale, 2)
    endif

    $rh_hue = 0
    if $rh_delta > 0 then
        if $rh_max = $rh_r and $rh_max <> $rh_g then
            $rh_hue += ($rh_g - $rh_b) / $rh_delta
        endif
        if $rh_max = $rh_g and $rh_max <> $rh_b then
            $rh_hue += 2 + ($rh_b - $rh_r) / $rh_delta
        endif
        if $rh_max = $rh_b and $rh_max <> $rh_r then
            $rh_hue += 4 + ($rh_r - $rh_g) / $rh_delta
        endif
        $rh_hue *= 60
    endif
    if $rh_hue < 0 then $rh_hue += 360 ; hack
    if $idx = 1 then return Round($rh_hue)

    $do_string = true
    if not $idx then
        $idx = ","
        $do_string = false
    endif

    local $hsl_arr[3]
    $hsl_arr[0] = Round($rh_hue)
    $hsl_arr[1] = Round($rh_saturation*$hsl_scale, 2)
    $hsl_arr[2] = Round($rh_lightness*$hsl_scale, 2)
    $hsl = $hsl_arr[0] & $idx & $hsl_arr[1] & $idx & $hsl_arr[2]

    if $do_string then return $hsl
    if $simple_array then return $hsl_arr
    return StringSplit($hsl$idx)
endfunc



; convert windows registry color to RGB Hex..
;
func RegColorToRGBHexColor($RegVal)
    $col = StringSplit($RegVal" ")
    if $col[0] < 2 then return ""
    return Hex($col[1], 2) & Hex($col[2], 2) &  Hex($col[3], 2)
endfunc



; returns an array with three elements (R, G, B)
func ConvertRGBtoDecArray($color)
    local $c_arr[3]
    $c_arr[0] = Dec(StringLeft($color, 2))
    $c_arr[1] = Dec(StringMid ($color, 3 , 2))
    $c_arr[2] = Dec(StringRight($color, 2))
    return $c_arr
endfunc



; I have other color conversion functions ;o)






; The standard AutoIt UDF color functions
; re-named and here for convenience
;
Func GetColorRed($nColor)
    Return BitAND(BitShift($nColor, 16), 0xff)
EndFunc

Func GetColorGreen($nColor)
    Return BitAND(BitShift($nColor, 8), 0xff)
EndFunc

Func GetColorBlue($nColor)
    Return BitAND($nColor, 0xff)
EndFunc





; ColorChooser() By Cor
;
; An alternative version of the system color chooser dialog function.
; This version can store and retrieve the 16 custom colors. Nifty.
;
; Send an array of 17 AutoIt RGB (e.g. 0xF0EBC3) colors, the first $array[0] being the
; color you wish to initially set in the picker, and the other 16, any custom colors
; you want to set. Empty values can be set to 0.
;
; Returns an array of 17 colors, $array[0] being the color "picked", and the other 16,
; any custom colors the user may have chosen. You can, of course, store these and then
; send them back to the color picker the next time it is called. At last! Store them
; in an ini file or wimilar and use them after next launch.
;
; NOTE: This function accepts and returns AutoIt RGB colors. If you need to convert to
; and from other color values, use ConvertColorValue(above)
;
func ColorChooser($CustomColors=0, $hWndOwnder=0)

    if not IsArray($CustomColors) or Ubound($CustomColors) < 17 then
        $CustomColors = StringSplit("0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"",", 2)
    endif

    local $ret_array[17], $color_picked$aResult

    local $custcolors = "int ccolors[16]"
    local $col_STRUCT = "dword Size;hwnd hWndOwnder;handle hInstance;dword rgbResult;ptr CustColors;dword Flags;lparam lCustData;ptr lpfnHook;ptr lpTemplateName"
    local $tChoose = DllStructCreate($col_STRUCT)
    local $tcc = DllStructCreate($custcolors)

    $CustomColors[0] = '0x' & StringMid($CustomColors[0], 7, 2) & StringMid($CustomColors[0], 5, 2) & StringMid($CustomColors[0], 3, 2)

    DllStructSetData($tChoose"Size", DllStructGetSize($tChoose))
    DllStructSetData($tChoose"hWndOwnder"$hWndOwnder)
    DllStructSetData($tChoose"rgbResult"$CustomColors[0])
    DllStructSetData($tChoose"CustColors", DllStructGetPtr($tcc))
    DllStructSetData($tChoose"Flags", BitOR($__MISCCONSTANT_CC_ANYCOLOR$__MISCCONSTANT_CC_FULLOPEN$__MISCCONSTANT_CC_RGBINIT))

    for $i = 1 to 16 ; set the custom colors..
        $ccolor = Dec(StringMid($CustomColors[$i], 7, 2) & StringMid($CustomColors[$i], 5, 2) & StringMid($CustomColors[$i], 3, 2))
        DllStructSetData($tcc"ccolors"$ccolor$i)
    next

    $aResult = DllCall("comdlg32.dll""bool""ChooseColor""struct*"$tChoose)
    if ($aResult[0] == 0) then return SetError(-3, -3, -1)
    if @error then return SetError(@error, @extended, -1)

    $color_picked = Hex(String(DllStructGetData($tChoose"rgbResult")), 6)
    if $color_picked < 0 then return SetError(-4, -4, -1)

    $ret_array[0] = '0x' & StringMid($color_picked, 5, 2) & StringMid($color_picked, 3, 2) & StringMid($color_picked, 1, 2)
    for $i = 1 to 16 ; create custom color array for return
        $cc = Hex(DllStructGetData($tcc"ccolors"$i), 6)
        $ret_array[$i] = '0x' & StringMid($cc, 5, 2) & StringMid($cc, 3, 2) & StringMid($cc, 1,   2)
    next
    return $ret_array
endfunc

#cs

; a full implementation..


; to store any system picked custom colors..
global $MyColors[17] = [""]


; System Color Picker..

func HotKeySystemPicker()
    SystemPicker($current_color)
endfunc

func SystemPicker($color)
    UnSetHotKeys()
    LoadCustomColors()
    $MyColors[0] = '0x' & $color
    $ret_colors = ColorChooser($MyColors$MyGUI)
    if @error then return false
    switch $ret_colors[0]
        case -1, -3, -4, ""
            SetHotKeys()
            return false
        case else
            $MyColors = $ret_colors
            $new_color = StringTrimLeft($MyColors[0], 2)
            SaveCustomColors()
            SetHotKeys()
    endswitch
endfunc

func SaveCustomColors()
    if not IsArray($MyColors) or UBound($MyColors) < 17 then return false
    local $color_str
    for $i = 1 to 16
        $color_str &= $MyColors[$i] & ","
    next
    $color_str = StringTrimRight($color_str, 1)
    if IniWrite($cpc_ini_path$cpc_my_name"custom_colors"$color_str) then return true
endfunc

func LoadCustomColors()
    local $color_str = IniRead($cpc_ini_path$cpc_my_name"custom_colors""")
    $MyColors = StringSplit($color_str",")
endfunc


#ce
back to the source menu
test

Welcome to corz.org!

I'm always messing around with the back-end.. See a bug? Wait a minute and try again. Still see a bug? Mail Me!