Matthy Posted December 28, 2008 Share Posted December 28, 2008 (edited) hi, i want to use the PixelGetColor to sort out images. but i have a problem. this type of colorgetting needs the X and a Y of your screen, and i want to run it at the background. in the help file i have seen something about a handle but can find how to use it. Example. i want to read the pixels a image on my pc (script dir) like test.jpg and check how many black pixels it has. it is possible with using the whole screen but then i cant do other stuff next to it. and have to let my pc on in the night. Meaby its very simple using the handle but dont know how to use that. anyone? Thanks Matthy EDIT: tried finding the handle of image prview in Autoit window info but it keeps changing so i dont think i can use that. or can i? Edited December 28, 2008 by Matthy Link to comment Share on other sites More sharing options...
igotandrew Posted December 29, 2008 Share Posted December 29, 2008 (edited) So you want a pixel finder / counter, to search a minimized or non-visible window?(Just trying to clarify things for future people)just found this:You can't do Pixel functions on a Non-Focused window. Edited December 29, 2008 by igotandrew Link to comment Share on other sites More sharing options...
Malkey Posted December 29, 2008 Share Posted December 29, 2008 (edited) hi, i want to use the PixelGetColor to sort out images. but i have a problem. this type of colorgetting needs the X and a Y of your screen, and i want to run it at the background. in the help file i have seen something about a handle but can find how to use it. Example. i want to read the pixels a image on my pc (script dir) like test.jpg and check how many black pixels it has. it is possible with using the whole screen but then i cant do other stuff next to it. and have to let my pc on in the night. Meaby its very simple using the handle but dont know how to use that. anyone? Thanks Matthy EDIT: tried finding the handle of image prview in Autoit window info but it keeps changing so i dont think i can use that. or can i?Black is colour 0x000000, in the RGB and BGR colour systems. 0x010101 may look black, and if searching for black,0x000000 will not find 0x010101. This example scripts finds all colours in an image file below 0x202020. You may be able to change it to suit your needs. expandcollapse popup;========================================================= ; Produces an array of pixel colours used in an image that are below the colour 0x202020 (array[n][0]), ; Number of times that colour is used (array[n][1]), and, ; the percentage of the numer of times the colour is used over the total number of pixels in the image (array[n][2]). ; Array[0][0] contains the number of unique pixels used in the image below 0x202020 colour. ; Array[0][1] contains the total number of pixels used in the image below 0x202020 colour. ; Array[0][2] contains the percentage of the total number of pixels used in the image below 0x202020 colour. ;============================================================ #include <WinAPI.au3> #include <ScreenCapture.au3> #include <GDIPlus.au3> #include <Array.au3> Dim $pixels, $iTotalReplace Local $Path = FileOpenDialog("Choose Image File", @ScriptDir & "", "Images (*.gif;*.png;*.jpg;*.bmp)| All (*.*)") If $Path <> "" Then _GDIPlus_Startup() $hImage = _GDIPlus_ImageLoadFromFile($Path) $width = _GDIPlus_ImageGetWidth($hImage) $height = _GDIPlus_ImageGetHeight($hImage) $hBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) $aSize = DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $hBmp, 'int', 0, 'ptr', 0) If $aSize[0] Then $tBits = DllStructCreate('byte[' & $aSize[0] & ']') DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $hBmp, 'int', $aSize[0], 'ptr', DllStructGetPtr($tBits)) $sHex = Hex(DllStructGetData($tBits, 1)) ; Selects all pixels below/less than 0x202020 $pixels = StringRegExp($sHex, "([01][0-9A-F][01][0-9A-F][01][0-9A-F])FF", 3) ; Selects all pixels below/less than 0x505050 (Can take a while) ;$pixels = StringRegExp($sHex, "([0-5][0-9A-F][0-5][0-9A-F][0-5][0-9A-F])FF", 3) $sHexReduced = _ArrayToString($pixels) & "|" Dim $pixels[1][3] While StringLen($sHexReduced) > 6 ReDim $pixels[UBound($pixels) + 1][3] $PixTemp = StringLeft($sHexReduced, 7) $sHexReduced = StringReplace($sHexReduced, $PixTemp, "", 0) $numreplacements = @extended $pixels[UBound($pixels) - 1][1] = $numreplacements $pixels[UBound($pixels) - 1][0] = StringTrimRight($PixTemp, 1) $pixels[UBound($pixels) - 1][2] = StringFormat("%1.4f%%", $numreplacements * 100 / ($height * $width)) $iTotalReplace += $numreplacements WEnd $pixels[0][0] = UBound($pixels) - 1 $pixels[0][1] = $iTotalReplace $pixels[0][2] = StringFormat("%1.4f%%", $iTotalReplace * 100 / ($height * $width)) EndIf _ArraySort($pixels, 0, 1, 0, 0) _ArrayDisplay($pixels,$Path) _WinAPI_DeleteObject($hBmp) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() EndIf Edit: Added & "|" to $sHexReduced = _ArrayToString($pixels) & "|" . At the end of the loop $sHexReduced is now empty. Edited December 29, 2008 by Malkey robertocm 1 Link to comment Share on other sites More sharing options...
Matthy Posted December 29, 2008 Author Share Posted December 29, 2008 Many thanks this was exactly what i was looking for Matthy Link to comment Share on other sites More sharing options...
myspacee Posted December 29, 2008 Share Posted December 29, 2008 (edited) omg. Don't think that possible. Have same request for other colors, is possible to implement sort of color picker ? (for set color range +-) m. Edited December 29, 2008 by myspacee Link to comment Share on other sites More sharing options...
Valuater Posted December 29, 2008 Share Posted December 29, 2008 Awesome!! 8) Link to comment Share on other sites More sharing options...
Matthy Posted December 29, 2008 Author Share Posted December 29, 2008 omg. Don't think that possible. Have same request for other colors, is possible to implement sort of color picker ? (for set color range +-) m. look at $pixels = StringRegExp($sHex, "([01][0-9A-F][01][0-9A-F][01][0-9A-F])FF", 3) here you can set your colour Link to comment Share on other sites More sharing options...
myspacee Posted December 29, 2008 Share Posted December 29, 2008 (edited) thank you Matthy, but need help to understand 'conversion' between human readable 'color' value and script string... help us a little more ? m. Edited December 29, 2008 by myspacee Link to comment Share on other sites More sharing options...
junkew Posted December 29, 2008 Share Posted December 29, 2008 (edited) I think you need to start reading on as there is a lot on colors and RGBhttp://www.w3schools.com/Html/html_colors.asphttp://en.wikipedia.org/wiki/RGB_color_modelhttp://en.wikipedia.org/wiki/RGB_color_spacehttp://www.rgbworld.com/color.htmlSummarized using cubes of http://en.wikipedia.org/wiki/RGB_color_spaceA color in RGB can be visualised as a cube.The cube consists of 256*256*256 different colors.If you have defined to know/see 8 human readable colors you should imagine the cube to consist of 8 equal cubes within the total cube.This means 4 cubes you can see if you look to the front of the cube.Lets call them cube 1 thru 4 the ones you see on the front and 5 thru 8 on the back. (5 is behind 1)Internal cube 1 can then be defined as yellow which are then all colors in the R > 128, G >128, B < 128Internal cube 5 can then be defined as red which are then all colors in the R > 128 , G < 128, B < 128** Note calculation above is not fully correct as the human eye interprets colors a little different Edited December 29, 2008 by junkew FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
junkew Posted December 29, 2008 Share Posted December 29, 2008 (edited) Based on the cube definition of yellow yellow = R from 80 thru FF, G from 80 thru FF, B from 0 thru 80 Unclear why there is an FF at the end but as it was in the original example I left it there ; Selects all pixels beeing "yellow" $pixels = StringRegExp($sHex, "([8-9A-F][0-9A-F][8-9A-F][0-9A-F][0-8][0-9A-F])FF", 3) Edited December 29, 2008 by junkew FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
myspacee Posted December 29, 2008 Share Posted December 29, 2008 ok, try to read rgb materials find around. In our production we work with CMYK, i know is a good exercise for me, but anyone has Malkey_junkew conversion already done for these colors/standard ? (Read a lot also for imagemagick, but Autoit is my favourite choice) thank you all, m. Link to comment Share on other sites More sharing options...
Malkey Posted December 30, 2008 Share Posted December 30, 2008 Unclear why there is an FF at the end but as it was in the original example I left it thereIf you look at the raw data in the string $sHex, it looks like the image has loaded with 32 bit colours with a RRGGBBAA colour format. The AA being the alpha channel. All the colours have "FF" in the alpha channel meaning that the RGB colour is fully opaque. The search only needed to return the RGB colour. This is my explanation of what I found in the $sHex string, and I hope that the colours are not really in ARGB format, and I've screwed something up. ok, try to read rgb materials find around. In our production we work with CMYK, i know is a good exercise for me, but anyone has Malkey_junkew conversion already done for these colors/standard ? (Read a lot also for imagemagick, but Autoit is my favourite choice) thank you all, m.Here is an example of two functions One converts RGB to CMYK - the RGBToCMYK () function, and the other converts CMYK to RGB - the CMYKToRGB () function. It is not completely accurate. A small error can be seen on some of the darker colours. expandcollapse popup#include <Math.au3> $Black = RGBToCMYK("000000") $Yellow = RGBToCMYK("FFFF00") $Mag = RGBToCMYK("FF00FF") $Cyan = RGBToCMYK("00FFFF") $Mar = RGBToCMYK("8B1C62") $Dark = RGBToCMYK("011C02") MsgBox(0, "Converts RGB Colour to CMYK and then converts CMYK to RGB", _ "RGB Colour black 0x000000 = CMYK " & $Black & " -> RGB " & CMYKToRGB($Black) & @CRLF & @CRLF & _ "RGB Colour yellow 0xFFFF00 = CMYK " & $Yellow & " -> RGB " & CMYKToRGB($Yellow) & @CRLF & @CRLF & _ "RGB Colour magenta 0xFF00FF = CMYK " & $Mag & " -> RGB " & CMYKToRGB($Mag) & @CRLF & @CRLF & _ "RGB Colour cyan 0x00FFFF = CMYK " & $Cyan & " -> RGB " & CMYKToRGB($Cyan) & @CRLF & @CRLF & _ "RGB Colour maroon 0x8B1C62 = CMYK " & $Mar & " -> RGB " & CMYKToRGB($Mar) & @CRLF & @CRLF & _ "RGB a dark colour 0x011C02 = CMYK " & $Dark & " -> RGB " & CMYKToRGB($Dark) & @CRLF & @CRLF) ;http://www.autoitscript.com/forum/index.php?s=&showtopic=54567&view=findpost&p=413494 ; RGBToCMYK() by corz ; ; 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" ; Modified Malkey Func RGBToCMYK($rgb_color, $norm = 1) If $rgb_color = "000000" Then Local $k = 1, $c = 0, $m = 0, $y = 0 Else ; get decimal rgb values and scale to 0-1.. $rc_r = (Dec(StringLeft($rgb_color, 2))) / 255 $rc_g = Dec(StringMid($rgb_color, 3, 2)) / 255 $rc_b = Dec(StringRight($rgb_color, 2)) / 255 ConsoleWrite("$rc_b " & $rc_b & @CR) $k = _Min(_Min(1 - $rc_r, 1 - $rc_g), 1 - $rc_b) ConsoleWrite(" $k " & $k & @CR) $c = (1 - $rc_r - $k) / (1 - $k) $m = (1 - $rc_g - $k) / (1 - $k) $y = (1 - $rc_b - $k) / (1 - $k) ConsoleWrite(" $y " & $y & @CR) EndIf 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 ;==>RGBToCMYK ; Not by corz Func CMYKToRGB($cmyk_color) Local $k, $rc_r, $rc_g, $rc_b, $rgb_color $aCMCK = StringRegExp(StringStripWS($cmyk_color, 8) & ",", "([0-9.]+),", 3) If $aCMCK[3] > 1 Or $aCMCK[0] > 1 Or $aCMCK[1] = 0 Or $aCMCK[2] > 1 Then $aCMCK[0] = $aCMCK[0] / 100 $aCMCK[1] = $aCMCK[1] / 100 $aCMCK[2] = $aCMCK[2] / 100 $aCMCK[3] = $aCMCK[3] / 100 EndIf If $aCMCK[3] = 1 And $aCMCK[0] = 0 And $aCMCK[1] = 0 And $aCMCK[2] = 0 Then $rgb_color = "000000" Else $k = $aCMCK[3] $rc_r = ($aCMCK[0] - 1) * (-1 + $k) * 255 $rc_g = ($aCMCK[1] - 1) * (-1 + $k) * 255 $rc_b = ($aCMCK[2] - 1) * (-1 + $k) * 255 $k = $k * 255 If $rc_r < 0 Then $rc_r = $k If $rc_g < 0 Then $rc_g = $k If $rc_b < 0 Then $rc_b = $k $rgb_color = Hex(Ceiling($rc_r), 2) & Hex(Ceiling($rc_g), 2) & Hex(Ceiling($rc_b), 2) EndIf Return $rgb_color EndFunc ;==>CMYKToRGB robertocm 1 Link to comment Share on other sites More sharing options...
Malkey Posted December 30, 2008 Share Posted December 30, 2008 (edited) This is a slightly modified version of my first reply with an added routine that shows the X Y positions of the found colours from the image file. It takes a longer time to complete. expandcollapse popup;========================================================= ; Produces two arrays:- ;First array contains the pixel colours used in an image that are below the colour 0x101010 (array[n][0]), ; Number of times that colour is used (array[n][1]), and, ; the percentage of the numer of times the colour is used over the total number of pixels in the image (array[n][2]). ; Array[0][0] contains the number of unique pixels used in the image below 0x101010 colour. ; Array[0][1] contains the total number of pixels used in the image below 0x101010 colour. ; Array[0][2] contains the percentage of the total number of pixels used in the image below 0x202020 colour. ; Second array contains all the pixel colours used in an image that are below the colour 0x101010 (array2[n][0]), and ; array2[n][1] contains the X position of the pixel colour in array2[n][0], and ; array2[n][2] contains the Y position of the pixel colour in array2[n][0]. ; The more colours found, the longer time it is going to take to complete. ;============================================================ #include <WinAPI.au3> #include <ScreenCapture.au3> #include <GDIPlus.au3> #include <Array.au3> Dim $pixels, $iTotalReplace,$Count = 0 Local $Path = FileOpenDialog("Choose Image File", @ScriptDir & "", "Images (*.gif;*.png;*.jpg;*.bmp)| All (*.*)") If $Path <> "" Then _GDIPlus_Startup() $hImage = _GDIPlus_ImageLoadFromFile($Path) $width = _GDIPlus_ImageGetWidth($hImage) $height = _GDIPlus_ImageGetHeight($hImage) $hBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) $aSize = DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $hBmp, 'int', 0, 'ptr', 0) If $aSize[0] Then $tBits = DllStructCreate('byte[' & $aSize[0] & ']') DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $hBmp, 'int', $aSize[0], 'ptr', DllStructGetPtr($tBits)) $sHex = Hex(DllStructGetData($tBits, 1)) $sHex = StringRegExpReplace($sHex, "([[:xdigit:]]{6})(FF)", "\1|") ; Find all green pixels, 0x00FF00 ;$pixels = StringRegExp($sHex, "(00FF00)\|", 3) ; Find all black pixels, 0x000000 ;$pixels = StringRegExp($sHex, "([0]{6})\|", 3) ; Selects all pixels below/less than 0x101010 $pixels = StringRegExp($sHex, "([0][0-9A-F][0][0-9A-F][0][0-9A-F])\|", 3) ; Selects all pixels below/less than 0x505050 (Can take a while) ;$pixels = StringRegExp($sHex, "([0-5][0-9A-F][0-5][0-9A-F][0-5][0-9A-F])\|", 3) $sHexReduced = _ArrayToString($pixels) & "|" Dim $pixels[20000][3] ; Max No. of entries in an array is 16,777,216 While StringLen($sHexReduced) > 6 ;ReDim $pixels[UBound($pixels) + 1][3] $PixTemp = StringLeft($sHexReduced, 7) $sHexReduced = StringReplace($sHexReduced, $PixTemp, "", 0) $numreplacements = @extended $Count += 1 $pixels[$Count][1] = $numreplacements $pixels[$Count][0] = StringTrimRight($PixTemp, 1) $pixels[$Count][2] = StringFormat("%1.4f%%", $numreplacements * 100 / ($height * $width)) $iTotalReplace += $numreplacements WEnd $pixels[0][0] = $Count $pixels[0][1] = $iTotalReplace $pixels[0][2] = StringFormat("%1.4f%%", $iTotalReplace * 100 / ($height * $width)) ReDim $pixels[$Count + 1][3] ;==== Find x y positions of the colours in the array ====== Dim $colPos[$iTotalReplace + 1][3] $colPos[0][0] = "Colour" $colPos[0][1] = "X Pos" $colPos[0][2] = "Y Pos" Local $Count = 0 For $n = 1 To $pixels[0][0] For $Rep = 1 To $pixels[$n][1] $Count += 1 $colPos[$Count][0] = $pixels[$n][0] $Pos = (StringInStr($sHex, $pixels[$n][0], 0, $Rep) - 1) / 7 $colPos[$Count][2] = Int($Pos / $width) ; Y Pos $colPos[$Count][1] = ($Pos - ($colPos[$Count][2] * $width)); X Pos Next Next ;=====> End of Find x y positions ===== EndIf _ArraySort($pixels, 0, 1, 0, 0) _ArraySort($colPos, 0, 1, 0, 2) _ArraySort($colPos, 0, 1, 0, 1) _ArrayDisplay($pixels, $width & "x" & $height & $Path) _ArrayDisplay($colPos, $width & "x" & $height & $Path) _WinAPI_DeleteObject($hBmp) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() EndIf Edit: Removed ReDim from inside loop. Edited December 30, 2008 by Malkey Link to comment Share on other sites More sharing options...
myspacee Posted December 30, 2008 Share Posted December 30, 2008 without words. m. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now