 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
ManaUser
Joined: 24 May 2007 Posts: 900
|
Posted: Thu Jun 28, 2007 9:23 pm Post subject: Color Pot - Color Grabber and Mixer |
|
|
I made this to to perform two related functions I've often wished my art program had. One is to sample the color of an area, rather than just one pixel and take the average. The other is to arbitrarily blend two or more colors together.
I'm fairly pleased with how it came out, though getting the result back into the art program is a little bit of a pain. You can either copy the hexadecimal color code, or a little square of the color itself, and you're on your own form there.
Here's a short description, as seen when clicking the help button: | Quote: | Color Pot can grab and mix colors found on the screen. Hold down the Windows Key to grab the color the mouse is pointing at. The color and its hex code will appear in the boxes labeled "Current". Clicking while holding down the Windows Key will add the color you're pointing at to the "Pot", the second two boxes. If there was already a color in the Pot, the colors will be combined. If you add multiple colors, they will be mixed in equal proportions. The number in ()s tells how many colors are in the Pot.
Left-clicking one of the hex labels or color boxes will copy the hex code or a small swatch of that color to the clipboard respectively.
Using the Sample Size dropdown you can have Color Pot draw color from a larger area instead of just one pixel. This might be useful when the sample is not a completely solid color.
You can also hold down these keys in addition to the Windows Key, with the following effects:
Shift - Replace the color in the Pot instead of adding to it.
Alt - Blend with the color in the Pot 1:1 even if it contains several samples.
Ctrl - Sample only one pixel, even if Sample Size is set larger.
Clicking the small square buttons will open the Windows color picker.
The Opt. button will open the options menu. Two options are available:
BGR Color Codes - Shows all colors in BGR format, instead of RGB.
Show Color Difference - Displays the difference between the Pot and the "Current" color. This includes both the difference in each primary color in signed hex and the greatest "variation" as used by the AHK Search commands, in decimal. For example if the Pot was 3310DB and Current was 2230AB it would display -1120-33 (48). Additionally the different between the Pot and the pixel under the cursor is displayed in a Tooltip when the Windows Key is held down. If the sample size is greater than Point this will display difference between the most different pixel, the most similar pixel and the average of all the pixels. |
| Code: | #NoEnv
#Persistent
#SingleInstance Force
#NoTrayIcon
SendMode Input
CoordMode Pixel, Screen
CoordMode Mouse, Screen
CoordMode ToolTip, Screen
SetTimer GetColor, 10
MixR := 0
MixG := 0
MixB := 0
MixNum := 0
Size := 1
CurColor = 0x000000
MixColor = 0x000000
OptShowDiff := 0
OptBGR := 0
Gui +ToolWindow +E0x40000 -Theme +AlwaysOnTop
Gui Add, Text, X4 Y0 H16 W64, Current
Gui Add, Text, X4 Y16 H24 W48 +0x200 +0x1000 Center vCurHexBox gCopyCurHex, 000000
Gui Add, ListView, X60 Y16 H24 W48 ReadOnly +0x4000 +Background000000 vCurColBox lv0x800000 0x4 -TabStop gCopyCurColor AltSubmit
Gui Add, Button, X112 Y20 H12 W12 -TabStop gCurColEdit,
Gui Add, Text, X44 Y40 H16 W80 BackgroundTrans Right vDiffLabel,
Gui Add, Text, X4 Y40 H16 W48 BackgroundTrans vMixedLabel, Pot (0)
Gui Add, Text, X4 Y56 H24 W48 +0x200 +0x1000 Center vMixHexBox gCopyMixHex, 000000
Gui Add, ListView, X60 Y56 H24 W48 ReadOnly +0x4000 +Background000000 vMixColBox lv0x800000 0x4 -TabStop gCopyMixColor AltSubmit
Gui Add, Button, X112 Y60 H12 W12 -TabStop gMixColEdit,
Gui Add, Text, X4 Y84 H16 W64, Sample Size:
Gui Add, DropDownList, X4 Y100 W56 vSize gSetSize Choose1, Point|3x3|5x5|7x7|9x9|11x11|13x13|15x15
Gui Add, Text, X64 Y100 H1 W1 0x4 vSampleSize
Gui Add, Button, X90 Y88 H16 W34 -TabStop gOptions, &Opt.
Gui Add, Button, X90 Y108 H16 W34 -TabStop gHelp, &Help
Gui Font, S9, Courier New
GuiControl Font, CurHexBox
GuiControl Font, MixHexBox
Gui Show, W128 H128, Color Pot
Menu Options, Add, Show Color Difference, MenuShowDiff
Menu Options, Add, BGR Color Codes, MenuBGR
;----------HotKeys---------
*#LButton::
If GetKeyState("Shift")
{
MixR := 0
MixG := 0
MixB := 0
MixNum := 0
}
Else If GetKeyState("Alt")
{
MixR /= MixNum
MixG /= MixNum
MixB /= MixNum
MixNum := 1
}
SetTimer GetColor, Off
GoSub GetColorNow
CurR := SubStr(CurColor, 1, 4)
CurG := "0x" . SubStr(CurColor, 5, 2)
CurB := "0x" . SubStr(CurColor, 7, 2)
MixR += CurR, MixG += CurG, MixB += CurB
MixNum += 1
SetFormat Integer, H
MixColor := Round(MixR/MixNum) * 65536 + Round(MixG/MixNum) * 256 + Round(MixB/MixNum)
SetFormat Integer, D
TidyHex(MixColor)
GuiControl +Background%MixColor%, MixColBox
GuiControl, , MixHexBox, % FormatHex(MixColor)
GuiControl, , MixedLabel, Pot (%MixNum%)
SetTimer GetColor, On
Return
~LWin:: ;This prevents the Windows Key from opening the
~RWin:: ;start menu if you hold it down for at least a second.
Return
;-----------Gui Subs-----------
SetSize:
Gui Submit, NoHide
If (Size = "Point")
Size := 1
Else
StringTrimLeft Size, Size, InStr(Size, "x")
GuiControl Move, SampleSize, H%Size% W%Size%
Return
CopyCurHex:
ClipBoard := FormatHex(CurColor)
Return
CopyCurColor:
If (A_GuiEvent == "F")
{
GuiControl Focus, Size
CopySwatch(CurColor)
}
Return
CopyMixHex:
ClipBoard := FormatHex(MixColor)
Return
CopyMixColor:
If (A_GuiEvent == "F")
{
GuiControl Focus, Size
CopySwatch(MixColor)
}
Return
Help:
Gui -AlwaysOnTop
MsgBox, 0, Help,
(
Color Pot can grab and mix colors found on the screen. Hold down the Windows Key to grab the color the mouse is pointing at. The color and its hex code will appear in the boxes labeled "Current". Clicking while holding down the Windows Key will add the color you're pointing at to the "Pot", the second two boxes. If there was already a color in the Pot, the colors will be combined. If you add multiple colors, they will be mixed in equal proportions. The number in ()s tells how many colors are in the Pot.
Left-clicking one of the hex labels or color boxes will copy the hex code or a small swatch of that color to the clipboard respectively.
Using the Sample Size dropdown you can have Color Pot draw color from a larger area instead of just one pixel. This might be useful when the sample is not a completely solid color.
You can also hold down these keys in addition to the Windows Key, with the following effects:
Shift - Replace the color in the Pot instead of adding to it.
Alt - Blend with the color in the Pot 1:1 even if it contains several samples.
Ctrl - Sample only one pixel, even if Sample Size is set larger.
Clicking the small square buttons will open the Windows color picker.
The Opt. button will open the options menu. Two options are available:
BGR Color Codes - Shows all colors in BGR format, instead of RGB.
Show Color Difference - Displays the difference between the Pot and the "Current" color. This includes both the difference in each primary color in signed hex and the greatest "variation" as used by the AHK Search commands, in decimal. For example if the Pot was 3310DB and Current was 2230AB it would display -1120-33 (48). Additionally the different between the Pot and the pixel under the cursor is displayed in a Tooltip when the Windows Key is held down. If the sample size is greater than Point this will display difference between the most different pixel, the most similar pixel and the average of all the pixels.
)
Gui +AlwaysOnTop
GuiControl Focus, Size
Return
CurColEdit:
NewColor := ChooseColor(CurColor, WinActive("A"))
If (NewColor != -1)
{
CurColor := "0x" . NewColor
GuiControl +Background%CurColor%, CurColBox
GuiControl, , CurHexBox, % FormatHex(CurColor)
}
GuiControl Focus, Size
Return
MixColEdit:
NewColor := ChooseColor(MixColor, WinActive("A"))
If (NewColor != -1)
{
MixColor := "0x" . NewColor
GuiControl +Background%MixColor%, MixColBox
GuiControl, , MixHexBox, % FormatHex(MixColor)
MixNum := 1
MixR := SubStr(MixColor, 1, 4)
MixG := "0x" . SubStr(MixColor, 5, 2)
MixB := "0x" . SubStr(MixColor, 7, 2)
GuiControl, , MixedLabel, Pot (%MixNum%)
}
GuiControl Focus, Size
Return
Options:
Menu Options, Show
GuiControl Focus, Size
Return
;--menu--
MenuShowDiff:
OptShowDiff := !OptShowDiff
Menu Options, ToggleCheck, Show Color Difference
If OptShowDiff
GuiControl, , DiffLabel, % GetDiff(FormatHex(MixColor), FormatHex(CurColor), 1)
else
GuiControl, , DiffLabel,
Return
MenuBGR:
OptBGR := !OptBGR
Menu Options, ToggleCheck, BGR Color Codes
Return
;--end menu--
GuiClose:
ExitApp
;-----------Other Subs and Functions-----------
GetColor:
If NOT (GetKeyState("LWin") OR GetKeyState("RWin"))
Return
GetColorNow:
MouseGetPos X, Y
If (Size = 1 OR GetKeyState("Ctrl"))
{
PixelGetColor CurColor, %X%, %Y%, RGB
If OptShowDiff
ShowToolTip(GetDiff(FormatHex(MixColor), FormatHex(CurColor)))
}
else
{
X -= Floor(Size/2)
Y -= Floor(Size/2)
CurR := 0, CurG := 0, CurB := 0
PixCount := 0
If OptShowDiff
{
MinDiff := 256
MaxDiff := -1
}
Loop % Size
{
Loop % Size
{
PixelGetColor PixColor, %X%, %Y%, RGB
PixR := SubStr(PixColor, 1, 4)
PixG := "0x" . SubStr(PixColor, 5, 2)
PixB := "0x" . SubStr(PixColor, 7, 2)
CurR += PixR, CurG += PixG, CurB += PixB
PixCount += 1
Y += 1
If OptShowDiff
GetMinMax(PixColor, MinDiff, MaxDiff)
}
X += 1
Y -= Size
}
If OptShowDiff
ShowToolTip("Min: " . MinLin . "`nMax: " . MaxLin . "`nAvg: " . GetDiff(FormatHex(MixColor), FormatHex(CurColor)))
SetFormat Integer, H
CurColor := Round(CurR/PixCount) * 65536 + Round(CurG/PixCount) * 256 + Round(CurB/PixCount)
SetFormat Integer, D
}
TidyHex(CurColor)
GuiControl +Background%CurColor%, CurColBox
GuiControl, , CurHexBox, % FormatHex(CurColor)
If OptShowDiff
GuiControl, , DiffLabel, % GetDiff(FormatHex(MixColor), FormatHex(CurColor), 1)
Return
TidyHex(ByRef MyHex)
{
;Makes uppercase and pads eith 0s
StringTrimLeft MyHex, MyHex, 2
MyHex := "00000" . MyHex
StringRight MyHex, MyHex, 6
StringUpper MyHex, MyHex
MyHex := "0x" . MyHex
Return
}
FormatHex(MyHex)
{
Global OptBGR
MyHex := SubStr(MyHex, 3)
If OptBGR
MyHex := RegExReplace(MyHex, "(..)(..)(..)", "$3$2$1")
Return MyHex
}
CopySwatch(MyColor)
{
Gui 2:-Caption +AlwaysOnTop
Gui 2:Color, %MyColor%
Gui 2:Show, H32 W32, Swatch
WinWaitActive Swatch
ClipBoard =
Send !{PrintScreen}
ClipWait, , 1
Gui 2:Destroy
}
GetDiff(BaseColor, CompColor, GuiMode = 0, ByRef AbsDiff = 0)
{
SetFormat Integer, H
OutString =
Loop 3
{
Foo := ("0x" . SubStr(CompColor, 1, 2))
Bar := ("0x" . SubStr(BaseColor, 1, 2))
ThisDiff := Foo - Bar
OutString .= ThisDiff
ThisDiff := Abs(ThisDiff)
If (ThisDiff < 0x10)
OutString := RegExReplace(OutString, "(.)$", "0$1") ;Add leading zero
AbsDiff := ThisDiff > AbsDiff ? ThisDiff : AbsDiff
BaseColor := SubStr(BaseColor, 3)
CompColor := SubStr(CompColor, 3)
}
SetFormat Integer, D
StringUpper OutString, OutString
StringReplace OutString, OutString, 0x, , All
AbsDiff += 0
If GuiMode
OutString .= " (" . AbsDiff . ")"
Else
OutString := "(" . AbsDiff . ") " . OutString
Return OutString
}
ShowToolTip(TipText)
{
ToolTip %TipText%
SetTimer KillToolTip, -1000
}
KillToolTip:
ToolTip
Return
GetMinMax(OthColor, ByRef MinDif, ByRef MaxDif)
{
Global MixColor, MinLin, MaxLin
CurLin := GetDiff(FormatHex(MixColor), FormatHex(OthColor), 0, AD)
If (Ad > MaxDif)
{
MaxDif := AD
MaxLin := CurLin
}
If (Ad < MinDif)
{
MinDif := AD
MinLin := CurLin
}
}
ChooseColor( Color=0x0, hPar=0x0, ccFile="") { ;Thanks Skan
Color := SubStr(Color,1,2)="0x" ? Color : "0x" Color ; Check & Prefix Color with "0x"
VarSetCapacity(CHOOSECOLOR, 36, 0) , mainPtr := (&CHOOSECOLOR) ; Create Main structure
DllCall( "RtlFillMemory", UInt,mainPtr+0, Int,1, UChar,36 ) ; Insert size of the Structure
hPar := WinExist(ahk_id %hPar%) ; Validate the passed Parent window ID
; Break Parent window ID into 4 bytes
H1 := hPar>>0 & 255, H2 := hPar>>8 & 255, H3 := hPar>>16 & 255, H4 := hPar>>24 & 255
Loop 4 ; Insert Parent window ID to CHOOSECOLOR structure @ Offset 4
DllCall( "RtlFillMemory", UInt,mainPtr+3+A_Index, Int,1, UChar,H%A_Index% )
; Break Color into R,G and B values
RGB1 := Color>>16 & 255, RGB2 := Color>>8 & 255, RGB3 := Color>>0 & 255
Loop 3 ; Insert R,G and B values to CHOOSECOLOR structure @ Offset 12
DllCall( "RtlFillMemory", UInt,mainPtr+11+A_Index, Int,1, UChar,RGB%A_Index% )
; CustomColors ( CUS1 will be primary array and CUS2 will be a copy to detect any change )
VarSetCapacity(CUS1, 64, 0), aPtr := (&CUS1), VarSetCapacity(CUS2, 64, 0)
IfEqual,ccFile,, SetEnv,ccFile,%A_WinDir%\CUSTOMCOLOR.BIN ; Assign default save filename
IfExist,%ccFile%, FileRead,CUS1, *m64 %ccFile% ; Array CUS1 will be overwritten
Loop 64 ; Copy data from CUS1 to CUS2
oS:=A_Index-1, DllCall( "RtlFillMemory", UInt,&CUS2+oS, Int,1, UChar,*(&CUS1+oS) )
A1 := aPtr>>0 & 255, A2 := aPtr>>8 & 255, A3 := aPtr>>16 & 255, A4 := aPtr>>24 & 255
Loop 4 ; Insert pointer to Custom colors array to CHOOSECOLOR structure @ Offset 16
DllCall( "RtlFillMemory", UInt,mainPtr+15+A_Index, Int,1, UChar,A%A_Index% )
; Insert Integer 259 @ Offset 21 (259 is CC_RGBINIT + CC_FULLOPEN + CC_ANYCOLOR )
DllCall( "RtlFillMemory", UInt,mainPtr+20, Int,1,UChar,3 ) ; CC_RGBINIT=1 + CC_FULLOPEN=2
DllCall( "RtlFillMemory", UInt,mainPtr+21, Int,1,UChar,1 ) ; CC_ANYCOLOR=256
If ! DllCall("comdlg32\ChooseColorA", str, CHOOSECOLOR) OR errorLevel ; Call ChooseColor
Return -1 ; and return -1 in case of an error or if no color was selected.
Loop 64 ; Compare data CUS2 and CUS1, if custom color changed, then save array to BIN file
If ( *(&CUS1+A_Index-1) != *(&CUS2+A_Index-1) ) { ; Check byte by byte
h := DllCall( "_lcreat", Str,ccFile, Int,0 ) ; Overwrite/create file
DllCall( "_lwrite", UInt,h, Str,CUS1, Int,64 ) ; write the array,
DllCall( "_lclose", UInt,h ) ; close the file,
Break ; break the loop.
}
Hex := "123456789ABCDEF0", RGB := mainPtr+11
Loop 3 ; Extract nibbles directly from main structure and convert it into Hex (initd. abv)
HexColorCode .= SubStr(Hex, (*++RGB >> 4), 1) . SubStr(Hex, (*RGB & 15), 1)
Return HexColorCode ; finally ... phew!
}
|
Update: New Show Difference and BGR options. Also direct access to the Windows color picker.
Last edited by ManaUser on Tue Jul 17, 2007 4:58 am; edited 1 time in total |
|
| Back to top |
|
 |
Titan
Joined: 11 Aug 2004 Posts: 5007 Location: imaginationland
|
Posted: Thu Jun 28, 2007 11:05 pm Post subject: |
|
|
This is very helpful, particularly for macroing when you need to find the common colour variation from a sample for PixelSearch. I have already found use for this so thanks. A couple suggestions: could you add a button to copy the code to the clipboard and have an BGR/RGB option. _________________
RegExReplace("irc.freenode.net/autohotkey", "^(?=(.(?=[\0-r\[]*((?<=\.).))))(?:[c-\x73]{2,8}(\S))+((2)|\b[^\2-]){2}\D++$", "$u3$1$3$4$2") |
|
| Back to top |
|
 |
ManaUser
Joined: 24 May 2007 Posts: 900
|
Posted: Fri Jun 29, 2007 4:28 am Post subject: |
|
|
It already has a feature to copy the code to the clipboard, just click the box displaying the code. BGR should be fairly easy, but just out of curiosity, when does one use that? I've never enounterde a need for it.
The other thing you said gave me an idea too. A feature for displaying the difference between two color could be very handy. That's that's exactly the kind of thing I was using this for myself, but I didn't think to build it in. Hmm... |
|
| Back to top |
|
 |
ManaUser
Joined: 24 May 2007 Posts: 900
|
Posted: Tue Jul 17, 2007 5:04 am Post subject: |
|
|
Update: New Show Difference and BGR options. Also direct access to the Windows color picker.
The format for showing the difference is a little strange, but it was the best I could think of. It subracts the R G and B values of the Pot from the current color and displays them in Hexadecimal and then shows the greastest difference (as used by ImageSearch and PixelSearch) in decimal. For example if the Pot was 3310DB and Current was 2230AB it would display -1120-33 (48). |
|
| Back to top |
|
 |
canadaman123 Guest
|
Posted: Wed Aug 15, 2007 4:12 pm Post subject: reset button |
|
|
| This is a great tool. It might be helpful to have a reset button to clear the pot and set the color back to 000000. Right now you can go find a black pixel and CTRL+SHIFT+LClick to reset it that way, but it would be nice to have a reset button. Maybe even "Reset to black" and "Reset to white" options. Just a thought. Great job though. |
|
| Back to top |
|
 |
Rhys
Joined: 17 Apr 2007 Posts: 618 Location: Florida
|
Posted: Fri May 09, 2008 6:57 pm Post subject: |
|
|
Holy cow this is really useful - Thanks! (Sorry to bump an old thread, but this is a really great little script and maybe now someone will see it who didn't before!) _________________
 |
|
| Back to top |
|
 |
pockinator
Joined: 06 Dec 2007 Posts: 32
|
Posted: Sun May 11, 2008 1:27 pm Post subject: |
|
|
This is a great little tool, ManaUser! And thanks for the bump, Rhys.  |
|
| Back to top |
|
 |
Wouther
Joined: 01 May 2007 Posts: 61 Location: The Netherlands
|
Posted: Sun May 11, 2008 3:28 pm Post subject: |
|
|
A wonderful tool! Thanks ManaUser!
I do agree with canadaman123, though: a button to reset the pot would be nice. Other than that, a very useful tool!
(And indeed thanks for the bump, Rhys, I didn't notice this until now. ) _________________ Printing css/html-formatted text |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|