Jump to content

Problem with Getting Color Shades


Recommended Posts

I have been trying to get shades of a color and have not had a lot of success.

I created a test program below, to help figure out what is happening, it is suppose to display one color in the first block and then 4 shades of that color.  Only have the first two squares working with this example. The color shade in color box 2 is way off.

I know this is a math thing, I just don't understand how to get the right formula to make this work.  I found 3 or 4 examples of math formula's around the web I tried which I commented into the program below.  My math is not that great so I have been trying various versions, not included below until I got too frustrated and came here to hopefully get help.

Ultimately this is going to be used in a custom color picker I am developing for a larger project. Put in a color code and get X amount of shades of that color.  

So far I am getting all sorts of colors only some of which are based on the original color.  White I get blues and sometimes greys though I have seen black, greens and reds for example. Depending on the math used.

Press 'ESC' key to exit the application.  It is just test code I put together so it is a bit over the place with console writes and test variables to play with various scenerios.

If I put in WHITE as a color I expect to see various shades of whites into light greys

Blacks should be various dark greys, charcoal colors etc...

Reds, Blues, Greens, Yellows etc...  should be various shades of the original color and not fluctuate visually into non-related colors from a visual stand point.  I understand color is made up of spectrums of Red, Blue, Green though when I choose a Green I want to see just shades of green for example. 

 

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7

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

HotKeySet("{ESC}","close")

#Region GUI Create
    Global $GUI = GUICreate("", 570, 145, -1, -1, $WS_BORDER + $WS_POPUP)
    Global $color_block0 = GUICtrlCreateLabel('', 10, 20, 100, 100)
    Global $color_block1 = GUICtrlCreateLabel('', 120, 20, 100, 100)
    Global $color_block2 = GUICtrlCreateLabel('', 230, 20, 100, 100)
    Global $color_block3 = GUICtrlCreateLabel('', 340, 20, 100, 100)
    Global $color_block4 = GUICtrlCreateLabel('', 450, 20, 100, 100)
    GUISetState(@SW_SHOW)
#EndRegion GUI Create

#Region Colors
    Global $shadeV
    Global $shade1
    Global $shade2
    Global $shade3
    Global $shade4

    ;~ Global $originalColor = $COLOR_WHITE
    ;~ Global $originalColor = 0x00294767
    ;~ Global $originalColor = $COLOR_AQUA
    Global $originalColor = $COLOR_GRAY
    ;~ Global $originalColor = $COLOR_BLACK
    ;~ Global $originalColor = $COLOR_PURPLE

    Global $rgb = _ColorGetRGB($originalColor)
    Global $hsl = _ColorConvertRGBtoHSL($rgb)
    Global $hexRGB = Hex($rgb[0], 2) & Hex($rgb[1], 2) & Hex($rgb[2], 2)
#EndRegion Colors

#Region Some Calculation Attempts

;~  $shadeV = 0.24

;~  $rgb[0] * (1 - $shadeV)
;~  $rgb[1] * (1 - $shadeV)
;~  $rgb[2] * (1 - $shadeV)

;~  ($rgb[0] * $shadeV) + $rgb[0]
;~  ($rgb[1] * $shadeV) + $rgb[1]
;~  ($rgb[2] * $shadeV) + $rgb[2]

;~  ($hsl[0] * $shadeV) + $hsl[0]
;~  ($hsl[1] * $shadeV) + $hsl[1]
;~  ($hsl[2] * $shadeV) + $hsl[2]

;~  $hsl[0] * $shadeV
;~  $hsl[1] * $shadeV
;~  $hsl[2] * $shadeV

#EndRegion Calculation Attempts

#Region Color Shade Calculations
    ConsoleWrite("ORIGINAL" & @CRLF)
    consoleWrite("HEX RGB: " & $hexRGB & @CRLF)
    consoleWrite("RGB: " & $rgb[0] & ', ' & $rgb[1] & ', ' & $rgb[2] & @CRLF)
    consoleWrite("HSL: " & Round($hsl[0], 2) & ', ' & Round($hsl[1], 2) & ', ' & Round($hsl[2], 2) & @CRLF)

    $shadeV = 0.24


    #Region RGB
        Global $rgbCalc = [$rgb[0] * (1 - $shadeV), $rgb[1] * (1 - $shadeV), $rgb[2] * (1 - $shadeV)]
        $shade1 = Hex($rgbCalc[0], 2) & Hex($rgbCalc[1], 2) & Hex($rgbCalc[2], 2)
    ;~  $shade2 =
    ;~  $shade3 =
    ;~  $shade4 =
    #EndRegion RGB

    #Region Console Write Log
        consoleWrite(@CRLF & "--------------------" & @CRLF)
        consoleWrite("RGB HEX shade1: " & Hex($shade1, 6) & @CRLF)
        consoleWrite("RGB shade1: " & $shade1 & @CRLF)
;~      consoleWrite("RGB HEX shade2: " & Hex($shade2, 6) & @CRLF)
;~      consoleWrite("RGB shade2: " & $shade2 & @CRLF)
;~      consoleWrite("RGB HEX shade3: " & Hex($shade3, 6) & @CRLF)
;~      consoleWrite("RGB shade3: " & $shade3 & @CRLF)
;~      consoleWrite("RGB HEX shade4: " & Hex($shade4, 6) & @CRLF)
;~     consoleWrite("RGB shade4: " & $shade4 & @CRLF)
        consoleWrite(@CRLF & "--------------------" & @CRLF)
    #EndRegion Console Write Log

    #Region HSL

;~  $shade1 = _ColorConvertRGBtoHSL($rgbCalc)


    #Region Console Write Log
;~  consoleWrite("HSL To RGB shade1: " & Round($shade1[0], 2) & " " & Round($shade1[1], 2) & " " & Round($shade1[2], 2) & @CRLF)
;~ consoleWrite("HSL To RGB shade2: " & $shade2 & @CRLF)
;~ consoleWrite("HSL To RGB shade3: " & $shade3 & @CRLF)
;~ consoleWrite("HSL To RGB shade4: " & $shade4 & @CRLF)
    #EndRegion Console Write Log

;~  HSL
;~  $shade1 = Round($shade1[0], 2) & Round($shade1[1], 2) & Round($shade1[2], 2)
;~  $shade2 =
;~  $shade3 =
;~  $shade4 =

    #EndRegion HSL


#EndRegion Color Shade Calculations


#Region Apply Colors
    GUICtrlSetBkColor($color_block0, $originalColor)
    GUICtrlSetBkColor($color_block1, $shade1)
    GUICtrlSetBkColor($color_block2, $shade2)
    GUICtrlSetBkColor($color_block3, $shade3)
    GUICtrlSetBkColor($color_block4, $shade4)
#EndRegion Apply Colors

While 1
    Sleep(10)
WEnd

Func close()
    Exit
EndFunc

 

Link to comment
Share on other sites

The problem in the end is a Math problem, I just don't understand how to calculate RGB, HEX version of RGB or HSL so that the color variations stay in that color spectrum and not go all over the place as I am seeing now.

Link to comment
Share on other sites

The following works for me... most of the time.

you need to break down the 6 digit hexidecimal color code to its rgb components.
To do that, split the 6 digit hex code into its 3 separate (2 digit) RGB components

Local $StartColor = 'insert your 6 digit hex here'
Local $lString = StringLeft($StartColor, 2)
Local $mString = StringMid($StartColor, 3, 2)
Local $rString = StringRight($StartColor, 2)

Then convert each of the 2 digit hex results to decmal and add ( to lighten) or subtract ( to darken)  in the range of 0-255
The greater the number used, the greater the possibility of changing the color completely.

Local $reddec = Dec($lString) + 30
Local $greendec = Dec($mString) + 30
Local $bluedec = Dec($rString) + 30

Then take each of these 3 decimal rgb results and convert them back to a 6 digit hexidecmal number

Local $newcolor = Hex($reddec, 2) & Hex($greeendec, 2) & Hex($bluedec, 2)

$newcolor is the slightly modified color you seek.

Edited by Shark007
Link to comment
Share on other sites

I have played a bit with the code, and finally i found a solution.

You can do it, as shark007 said, by substracting/adding 30 from r,g and b components.

Or you can calculate the percentage of the color, and adding it to the number.

The discovery was that the HEX() does not work well with floating point numbers.

Here are my playings with it:

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

HotKeySet("{ESC}", "close")


Global $GUI = GUICreate("", 570, 245)
Global $color_block0 = GUICtrlCreateLabel('', 10, 20, 50, 50)
Global $color_block1 = GUICtrlCreateLabel('', 120, 20, 100, 100)
Global $color_block2 = GUICtrlCreateLabel('', 230, 20, 100, 100)
Global $color_block3 = GUICtrlCreateLabel('', 340, 20, 100, 100)
Global $color_block4 = GUICtrlCreateLabel('', 450, 20, 100, 100)
Global $BTN = GUICtrlCreateButton("Doit", 5, 130, 50, 20)
Global $BTN1 = GUICtrlCreateButton("Random Color", 145, 130, 100, 20)
GUISetState(@SW_SHOW)


Global $shadeV
Global $shade1
Global $shade2
Global $shade3
Global $shade4
Global $originalColor
Global $rgb[3]
Global $hexRGB
Global $CR, $CB, $CG


$rgb[0] = 255
$rgb[1] = 200
$rgb[2] = 0

$hexRGB = "0x" & Hex($rgb[0], 2) & Hex($rgb[1], 2) & Hex($rgb[2], 2)
$originalColor = $hexRGB

ConsoleWrite("ORIGINAL" & @CRLF)
ConsoleWrite("HEX RGB: " & $hexRGB & @CRLF)
ConsoleWrite("RGB: " & $rgb[0] & ', ' & $rgb[1] & ', ' & $rgb[2] & @CRLF & @CRLF)

$shadeV =0.2
TheRGB()
ApplyColors()

While 1
    Sleep(10)
    Local $g = GUIGetMsg()
    If $g = $BTN Then
        TheRGB()
        ApplyColors()
    EndIf
    If $g = $BTN1 Then
        $rgb[0] = Int(Random(0, 255))
        $rgb[1] = Int(Random(0, 255))
        $rgb[2] = INT(Random(0, 255))
        $hexRGB = "0x" & Hex($rgb[0], 2) & Hex($rgb[1], 2) & Hex($rgb[2], 2)
        $originalColor = $hexRGB
        ConsoleWrite ("-> "& $hexRGB)
        TheRGB()
        ApplyColors()
    EndIf
WEnd

Func close()
    Exit
EndFunc   ;==>close

Func TheRGB()
    $shade1 = CalcRGB($rgb[0], $rgb[1], $rgb[2])
    $shade2 = CalcRGB($CR, $CG, $CB)
    $shade3 = CalcRGB($CR, $CG, $CB)
    $shade4 = CalcRGB($CR, $CG, $CB)
    $rgb[0] = $CR
    $rgb[1] = $CG
    $rgb[2] = $CB
EndFunc   ;==>TheRGB

Func CalcRGB($r, $g, $b)
;~   $shadeV=30                 ; Alternative calculation
;~  $CR = $r - $shadeV
;~  $CG = $g - $shadeV
;~  $CB = $b - $shadeV
    $CR = $r + int((255-$r)* $shadeV)
    $CG = $g + int((255-$g)* $shadeV)
    $CB = $b + int((255-$b)* $shadeV)
    If $CR > 255 Then $CR = 255
    If $CG > 255 Then $CG = 255
    If $CB > 255 Then $CB = 255
    If $CR < 0 Then $CR = 0
    If $CG < 0 Then $CG = 0
    If $CB < 0 Then $CB = 0
    ConsoleWrite(" -- " & $CR & " " & $CG & " " & $CB & @CRLF)
    ConsoleWrite(Hex($CR, 2) & " " & Hex($CG, 2) & " " & Hex($CB, 2) & @CRLF & @CRLF)
    Return "0x" & Hex($CR, 2) & Hex($CG, 2) & Hex($CB, 2)
EndFunc   ;==>CalcRGB

Func ApplyColors()
    GUICtrlSetBkColor($color_block0, $originalColor)
    GUICtrlSetBkColor($color_block1, $shade1)
    GUICtrlSetBkColor($color_block2, $shade2)
    GUICtrlSetBkColor($color_block3, $shade3)
    GUICtrlSetBkColor($color_block4, $shade4)
EndFunc   ;==>ApplyColors

 

Edited by Dan_555

Some of my script sourcecode

Link to comment
Share on other sites

I cleaned up the code and put the color pick and shading in a function
Based off of Shark007's code.

Also set the color pick to the position of the mouse pointer for easy testing.

 

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7

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

HotKeySet("{ESC}","close")

#Region GUI Create
    Global $GUI = GUICreate("", 570, 165, -1, -1, $WS_BORDER)
    Global $color_block0 = GUICtrlCreateLabel('', 10, 20, 100, 100)
    Global $color_block1 = GUICtrlCreateLabel('', 120, 20, 100, 100)
    Global $color_block2 = GUICtrlCreateLabel('', 230, 20, 100, 100)
    Global $color_block3 = GUICtrlCreateLabel('', 340, 20, 100, 100)
    Global $color_block4 = GUICtrlCreateLabel('', 450, 20, 100, 100)
    GUISetState(@SW_SHOW)
#EndRegion GUI Create

Func getColor()
    Local $getMPos, $originalColor
    Local $shade[5], $shadeV
    Local $rgb, $redDec, $greenDec, $blueDec

    $getMPos = MouseGetPos()
    $originalColor = Hex(PixelGetColor($getMPos[0], $getMPos[1]), 6)

    $rgb = _ColorGetRGB('0x00' & $originalColor)

;~  Color Shades
    $shadeV = 30
    For $i = 1 To 4 Step 1
        $redDec = Dec($rgb[0]) + $shadeV
        $greenDec = Dec($rgb[1]) + $shadeV
        $blueDec = Dec($rgb[2]) + $shadeV
        $shade[$i] = Hex($redDec, 2) & Hex($greenDec, 2) & Hex($blueDec, 2)
        $shadeV += 30
    Next
;~  End Color Shades

    GUICtrlSetBkColor($color_block0, '0x00' & $originalColor)
    GUICtrlSetBkColor($color_block1, '0x00' & $shade[1])
    GUICtrlSetBkColor($color_block2, '0x00' & $shade[2])
    GUICtrlSetBkColor($color_block3, '0x00' & $shade[3])
    GUICtrlSetBkColor($color_block4, '0x00' & $shade[4])
EndFunc

While 1
    getColor()
    Sleep(50)
WEnd

Func close()
    Exit
EndFunc



This seems to mostly work with Darker colors. Lighter colors don't do well with the shading.
 

Link to comment
Share on other sites

#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7

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

HotKeySet("{ESC}","close")

#Region GUI Create
    Global $GUI = GUICreate("", 570, 165, -1, -1, $WS_BORDER)
    Global $color_block0 = GUICtrlCreateLabel('', 10, 20, 100, 100)
    Global $color_block1 = GUICtrlCreateLabel('', 120, 20, 100, 100)
    Global $color_block2 = GUICtrlCreateLabel('', 230, 20, 100, 100)
    Global $color_block3 = GUICtrlCreateLabel('', 340, 20, 100, 100)
    Global $color_block4 = GUICtrlCreateLabel('', 450, 20, 100, 100)
    GUISetState(@SW_SHOW)
#EndRegion GUI Create

Global $CR, $CB, $CG

Func getColor()
    Local $getMPos, $originalColor
    Local $shade[5], $shadeV
    Local $rgb

;~  Get Color
    $getMPos = MouseGetPos()
    $originalColor = Hex(PixelGetColor($getMPos[0], $getMPos[1]), 6)

    $rgb = _ColorGetRGB('0x' & $originalColor)

;~  Get Color Shades
    $shadeV = 0.2
    $shade[0] = calcRGB($rgb[0], $rgb[1], $rgb[2], $shadeV)
    For $i = 1 To 4 Step 1
        $shade[$i] = calcRGB($CR, $CG, $CB, $shadeV)
    Next

;~  Apply Color Shades
    GUICtrlSetBkColor($color_block0, '0x00' & $originalColor)
    GUICtrlSetBkColor($color_block1, '0x00' & $shade[1])
    GUICtrlSetBkColor($color_block2, '0x00' & $shade[2])
    GUICtrlSetBkColor($color_block3, '0x00' & $shade[3])
    GUICtrlSetBkColor($color_block4, '0x00' & $shade[4])
EndFunc   ;==>getColor

Func CalcRGB($r, $g, $b, $shade)
    $CR = $r + int((255-$r) * $shade)
    $CG = $g + int((255-$g) * $shade)
    $CB = $b + int((255-$b) * $shade)
    If $CR > 255 Then $CR = 255
    If $CG > 255 Then $CG = 255
    If $CB > 255 Then $CB = 255
    If $CR < 0 Then $CR = 0
    If $CG < 0 Then $CG = 0
    If $CB < 0 Then $CB = 0
    Return Hex($CR, 2) & Hex($CG, 2) & Hex($CB, 2)
EndFunc   ;==>CalcRGB

While 1
    getColor()
    Sleep(150)
WEnd

Func close()
    Exit
EndFunc

 

Variation on Dan_555 code, converted to the code I wrote above with getting color under mouse pointer.

This seems to work Dan_555.  I like your Do It button that makes lighter and lighter shades...  Nice!

At first glance Pure White 255, 255, 255 OR #FFFFFF does not give shades but I did not console write the shades color.  Slight variation off of PURE White does give shades..  
I like this..  is a nice proof of concept.

Thank you Dan_555.

 

Link to comment
Share on other sites

GUICtrlSetBkColor($color_block0, '0x00' & $originalColor)
GUICtrlSetBkColor($color_block0, '0x' & $originalColor)

In the last code above I see no difference in sending the above to the Label Control for the colors.  The first two digits are for the transparency but I see no difference with either version above.  I should though, technically.  In other code I have written it is important to add the first two 00's..  some controls you have to use FF's I guess the transparency values are reversed on some controls?

But if you do this

GUICtrlSetBkColor($color_block0, $originalColor)

Color is WAY off.

Interesting experiment results.
 

Edited by iAmNewbe
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...