Jump to content

three color functions


corz
 Share

Recommended Posts

I've got quite a lot of home-brew functions, includes and snippets that are hidden away inside bigger things, so I figured it might be good to pull some of them out for closer inspection and wider attention. Here are three color and color value conversion functions I cooked up for my color pickin chooser, enabling (along with the sort functions in corz_essentials.au3) all sorts of groovy color sorting (something I forgot to mention in the color pickin chooser post).

ConvertColorValue()

RGBToCMYK()

RGBToHSL()

#include-once
#include <corz_essentials.au3>

#cs

  corz color functions v0.3
  miscellaneous functions for manipulating colors and their values
  (c) corz.org 2007


    function list..

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

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

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

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

#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")
;
func ConvertColorValue($color, $mode="web", $prefix=false, $index=0)
    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 = ""
    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="", $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
    $hsl = Round($rh_hue) & $idx & Round($rh_saturation*$hsl_scale, 2) & $idx & Round($rh_lightness*$hsl_scale, 2)

    if $do_string then return $hsl
    return StringSplit($hsl, $idx)
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

I've re-used them a few times myself.

You can get a zip of this, along with a few other includes, here.

have fun!

;o)

(or

nothing is foolproof to the sufficiently talented fool..

Link to comment
Share on other sites

  • 8 months later...

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...