cyxstudio Posted March 11, 2019 Share Posted March 11, 2019 In javascript you can get all the pixel colours of a large image in and instant with canvas.getImageData but for autoit pixelgetcolor only returns a single pixel hence i have to use a loop to get all pixelcolors of an image but it can take quite a long time if the image is large enough. Are there any ways to get array of pixelcolour of an image quickly? Link to comment Share on other sites More sharing options...
Nine Posted March 11, 2019 Share Posted March 11, 2019 GDI+ (look at GDIPlus Reference in help file along with ScreenCapture Management) “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
InnI Posted March 11, 2019 Share Posted March 11, 2019 (edited) 2 hours ago, cyxstudio said: get array of pixelcolour of an image #include <ScreenCapture.au3> $hBitmap = _ScreenCapture_Capture() Global $tSize = _WinAPI_GetBitmapDimension($hBitmap), _ $iWidth = $tSize.X, $iHeight = $tSize.Y, $iIndex, _ $iSize = $iWidth * $iHeight, $aPixels[$iHeight][$iWidth], _ $tBits = DllStructCreate("dword[" & $iSize & "]") _WinAPI_GetBitmapBits($hBitmap, 4 * $iSize, DllStructGetPtr($tBits)) _WinAPI_DeleteObject($hBitmap) For $i = 0 To $iHeight - 1 For $j = 0 To $iWidth - 1 $iIndex += 1 $aPixels[$i][$j] = DllStructGetData($tBits, 1, $iIndex) Next Next ;~ #include <Array.au3> ;~ _ArrayDisplay($aPixels) Edited March 11, 2019 by InnI FrancescoDiMuro 1 Link to comment Share on other sites More sharing options...
Nine Posted March 11, 2019 Share Posted March 11, 2019 (edited) @cyxstudio & @InnI I would not recommend using _WinAPI_GetBitmapBits. GetBitMapBits() is not impossible to use, but a lot harder because you need to "figure out" the format of the pixel information returned and extract the desired information. There are lots of possible formats, it would be a pain. Better use _WinAPI_GetDIBits. GetDIBits will converts the pixel information from the stored format to any format you want. But the best tool IMO remains GDI+. Edited March 11, 2019 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
AndyG Posted March 11, 2019 Share Posted March 11, 2019 (edited) Hi, the question is, why does anyone need an "AutoIt-Array of Pixels", every bitmap IS an array of width x height "pixels". So reading $aPixels[$i][$j] = DllStructGetData($tBits, 1, $iIndex) causes me physical pain...the slowest and wasteful memory method to "store" a bitmap...which is by the way loaded in RAM at this time... Not that i prefer _GDIPlus_BitmapLockBits to get a pointer to a bitmap or CreateDIBSection (which gives you pointer/handle/DC...) but once you got the pointer, you can easily catch the color of the x- and y-koordinates by simply addressing it. $color = DllStructGetData($tBits, 1, ($Width*$y + $x) ;x and y are the koordinates (0-based) of the "pixel" in the bitmap Yes, AutoIt is very slow with calculations within nested loops, but dllstructgetdata() is as fast as $aPixels[$i][$j]. Very much faster are all native String-Functions in AutoIt. You can use them to find or manipulate "colors" in a bitmap: $tBits = DllStructCreate("char[" & $iSize*4 & "]") ;every ARGB is a "word" of 4 char gives you access to a "string". So a "pixelsearch" is easily and superfast done with a StringInstr()... Edited March 11, 2019 by AndyG Bilgus and Nine 1 1 Link to comment Share on other sites More sharing options...
Nine Posted March 11, 2019 Share Posted March 11, 2019 1 hour ago, AndyG said: Very much faster are all native String-Functions in AutoIt. You can use them to find or manipulate "colors" in a bitmap: $tBits = DllStructCreate("char[" & $iSize*4 & "]") ;every ARGB is a "word" of 4 char gives you access to a "string". So a "pixelsearch" is easily and superfast done with a StringInstr()... Hmmm, I am kind of skeptical. You seem to pretend that we could use struct as an input to standard function of autoit like StringInStr(). Make my day, show me an example... “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
InnI Posted March 12, 2019 Share Posted March 12, 2019 12 hours ago, Nine said: show me an example Get an array of pixels of a certain color expandcollapse popup#include <ScreenCapture.au3> #include <Array.au3> $iColor = 0xFF0000 ; red $hBitmap = _ScreenCapture_Capture() Global $iIndex, $tSize = _WinAPI_GetBitmapDimension($hBitmap), _ $iWidth = $tSize.X, $iHeight = $tSize.Y, $iSize = $iWidth * $iHeight, _ $aPixels[$iSize + 1][2] ; DllStructGetData test $iTime = TimerInit() $tBits = DllStructCreate("dword[" & $iSize & "]") _WinAPI_GetBitmapBits($hBitmap, $iSize * 4, DllStructGetPtr($tBits)) For $i = 0 To $iHeight - 1 For $j = 0 To $iWidth - 1 $iIndex += 1 If BitAND(DllStructGetData($tBits, 1, $iIndex), 0x00FFFFFF) = $iColor Then $aPixels[0][0] += 1 $aPixels[$aPixels[0][0]][0] = $j $aPixels[$aPixels[0][0]][1] = $i EndIf Next Next ReDim $aPixels[$aPixels[0][0] + 1][2] ConsoleWrite("DllStructGetData: " & Round(TimerDiff($iTime)) & "ms" & @CRLF) _ArrayDisplay($aPixels) ; StringInStr test $iTime = TimerInit() $tBits = DllStructCreate('byte[' & $iSize * 4 & ']') _WinAPI_GetBitmapBits($hBitmap, $iSize * 4, DllStructGetPtr($tBits)) $sText = StringTrimLeft(DllStructGetData($tBits, 1), 2) $iStep = $iWidth * 8 Dim $aPixels[$iSize + 1][2], $aLines[$iHeight], $c = 0 For $i = 1 To StringLen($sText) Step $iStep $aLines[$c] = StringMid($sText, $i, $iStep) $c += 1 Next Dim $iPos, $iStart, $iLen = StringLen($aLines[0]) $iColor = StringRegExpReplace(Hex($iColor, 6), "(.{2})(.{2})(.{2})", "$3$2$1") For $i = 0 To $iHeight - 1 $iStart = 1 While $iStart <= $iLen $iPos = StringInStr($aLines[$i], $iColor, 1, 1, $iStart) If $iPos Then If Mod($iPos - 1, 8) Then $iStart = $iPos + 2 ContinueLoop EndIf $aPixels[0][0] += 1 $aPixels[$aPixels[0][0]][0] = ($iPos - 1) / 8 $aPixels[$aPixels[0][0]][1] = $i $iStart = $iPos + 8 Else ExitLoop EndIf WEnd Next ReDim $aPixels[$aPixels[0][0] + 1][2] ConsoleWrite("StringInStr: " & Round(TimerDiff($iTime)) & "ms" & @CRLF) _ArrayDisplay($aPixels) _WinAPI_DeleteObject($hBitmap) Nine and Bilgus 1 1 Link to comment Share on other sites More sharing options...
Bilgus Posted March 12, 2019 Share Posted March 12, 2019 (edited) @Nine AndyG is very much correct Local $iSize = 4096 Local $tBits = DllStructCreate("char[" & $iSize * 4 & "]") ;every ARGB is a "word" of 4 char Local $sAlpha = "ACTG" For $i = 1 To $iSize * 4 DllStructSetData($tBits, 1, StringMid($sAlpha, Random(1, 4, 1), 1), $i) Next ConsoleWrite(StringInStr(DllStructGetData($tBits, 1), "TAGC") & @crlf) @InnI Showoff Edited March 12, 2019 by Bilgus Nine 1 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