Quantcast
Channel: AutoIt v3 - General Help and Support
Viewing all articles
Browse latest Browse all 12506

Paint Bot

$
0
0
I have a paint application where I can enter into a console a hex code to change the color. I'm trying to make it so that I can load an image and the bot will examine the pixels, create a unique array of all colors. Afterwards, loop over the image looking for each color and then paint the pixel in every location that the image has a pixel of that color.

What I've written will process the image and get the colors. Then, when looping over the unique color array, it will change the color using the console but often times doesn't paint any pixels. This behavior doesn't make since because it got the colors from the image originally. Therefore, it should be painting at least 1 pixel per color found...

Also, it occasionally switches/pulls a random screen from the background forwards and messes up even more.

Basically:
Shift + Alt + S sets the mouse offset for where the image should be drawn.
Shift + Alt + C sets the location to click within the console window
Alt + S pauses the painting loop

Here is the code:
[ autoit ]         
;image control from memory coded by UEZ 2011 #include <GUIConstantsEx.au3> #include <GDIPlus.au3> #include <Array.au3> #Include <memory.au3> HotKeySet("!s", "ToggleRunning") HotKeySet("+!s", "SetOffset") HotKeySet("+!c", "SetConsoleBox") _GDIPlus_Startup() Global Const $IMAGE_BITMAP = 0 Global Const $STM_SETIMAGE = 0x0172 Global $msg Global Const $hBmp = Load_BMP_From_Mem(InetRead("https://www.google.com/images/srpr/logo3w.png"), True) ;to load an image from the net Global Const $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBmp) Global Const $iWidth = _GDIPlus_ImageGetWidth($hBitmap) Global Const $iHeight = _GDIPlus_ImageGetHeight($hBitmap) Global Const $hGUI = GUICreate("Display PNG Image in picture control", $iWidth, $iHeight) Global Const $idPic = GUICtrlCreatePic("", 0, 0, $iWidth, $iHeight) _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hBmp)) GUISetState() Global $running = False Global $currX = 0 Global $currY = 0 Global $offset = 0 Global $consoleBox = 0 Global $colorArray[1] ; Color to skip, normally a background color ; you wish to be transparent $colorArray[0] = "#gggggg" ; Process the image For $row = 0 to $iHeight     ConsoleWrite("Processing image... Row: " & $row & "/" & $iHeight & @LF)     For $col = 0 to $iWidth         $color = _GDIPlus_BitmapGetPixel($hBitmap, $row, $col)         Local $iIndex = _ArraySearch($colorArray, $color, 0, 0, 0, 1)         If @error Then             _ArrayAdd( $colorArray, $color )         EndIf     Next Next ConsoleWrite("Processing complete... Found " & UBound( $colorArray ) & " colors" & @LF) ; Main loop While True     $msg = GUIGetMsg()     Switch $msg         Case $idPic             MsgBox(0, "Information", "PNG image was clicked")         Case $GUI_EVENT_CLOSE             _WinAPI_DeleteObject($hBmp)             _GDIPlus_BitmapDispose($hBitmap)             _GDIPlus_Shutdown()             GUIDelete($hGUI)             Exit     EndSwitch     ; Drawing loop     If Not ($offset == 0) And Not ($consoleBox == 0) And $running Then         For $i = 1 to UBound( $colorArray ) - 1             MouseClick ( "left", $consoleBox[0], $consoleBox[1] )             Send("{#}" & $colorArray[ $i ])             Send("{Enter}")             For $col = $currY to $iHeight                 For $row = $currX to $iWidth                     $color = _GDIPlus_BitmapGetPixel($hBitmap, $row, $col)                     If $colorArray[ $i ] = $color Then                         ConsoleWrite($colorArray[ $i ] & " :: " & $color & @LF)                         MouseClick ( "left", $offset[0] + $currX, $offset[1] + $currY )                         Sleep ( 100 )                     EndIf                     $currX += 1                 Next                 $currY += 1             Next             $currX = 0             $currY = 0             Sleep ( 3000 )         Next     EndIf WEnd Func SetOffset()     $offset = MouseGetPos(); EndFunc Func SetConsoleBox()     $consoleBox = MouseGetPos(); EndFunc Func ToggleRunning()     $running = Not $running;     While Not ($running)         Sleep( 1000 )     WEnd EndFunc ;====================================================================================== ; Function Name:    Load_BMP_From_Mem ; Description:          Loads an image which is saved as a binary string and converts it to a bitmap or hbitmap ; ; Parameters:           $bImage:    the binary string which contains any valid image which is supported by GDI+ ; Optional:                 $hHBITMAP:  if false a bitmap will be created, if true a hbitmap will be created ; ; Remark:                   hbitmap format is used generally for GUI internal images, $bitmap is more a GDI+ image format ;                               Don't forget _GDIPlus_Startup() and _GDIPlus_Shutdown() ; ; Requirement(s):       GDIPlus.au3, Memory.au3 and _GDIPlus_BitmapCreateDIBFromBitmap() from WinAPIEx.au3 ; Return Value(s):  Success: handle to bitmap (GDI+ bitmap format) or hbitmap (WinAPI bitmap format), ;                               Error: 0 ; Error codes:              1: $bImage is not a binary string ;                               2: unable to create stream on HGlobal ;                               3: unable to create bitmap from stream ; ; Author(s):                UEZ ; Additional Code:    thanks to progandy for the MemGlobalAlloc and tVARIANT lines and ;                               Yashied for _GDIPlus_BitmapCreateDIBFromBitmap() from WinAPIEx.au3 ; Version:                  v0.97 Build 2012-04-10 Beta ;======================================================================================= Func Load_BMP_From_Mem($bImage, $hHBITMAP = False)     If Not IsBinary($bImage) Then Return SetError(1, 0, 0)     Local $aResult     Local Const $memBitmap = Binary($bImage) ;load image  saved in variable (memory) and convert it to binary     Local Const $len = BinaryLen($memBitmap) ;get length of image     Local Const $hData = _MemGlobalAlloc($len, $GMEM_MOVEABLE) ;allocates movable memory  ($GMEM_MOVEABLE = 0x0002)     Local Const $pData = _MemGlobalLock($hData) ;translate the handle into a pointer     Local $tMem = DllStructCreate("byte[" & $len & "]", $pData) ;create struct     DllStructSetData($tMem, 1, $memBitmap) ;fill struct with image data     _MemGlobalUnlock($hData) ;decrements the lock count  associated with a memory object that was allocated with GMEM_MOVEABLE     $aResult = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "handle", $pData, "int", True, "ptr*", 0) ;Creates a stream object that uses an HGLOBAL memory handle to store the stream contents     If @error Then Return SetError(2, 0, 0)     Local Const $hStream = $aResult[3]     $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $hStream, "int*", 0) ;Creates a Bitmap object based on an IStream COM interface     If @error Then Return SetError(3, 0, 0)     Local Const $hBitmap = $aResult[2]     Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")     DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, _                                            "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT)) ;release memory from $hStream to avoid memory leak     $tMem = 0     $tVARIANT = 0     If $hHBITMAP Then         Local Const $hHBmp = _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap)         _GDIPlus_BitmapDispose($hBitmap)         Return $hHBmp     EndIf     Return $hBitmap EndFunc   ;==>Load_BMP_From_Mem Func _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap)     Local $tBIHDR, $Ret, $tData, $pBits, $hResult = 0     $Ret = DllCall($ghGDIPDll, 'uint', 'GdipGetImageDimension', 'ptr', $hBitmap, 'float*', 0, 'float*', 0)     If (@error) Or ($Ret[0]) Then Return 0     $tData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $Ret[2], $Ret[3], $GDIP_ILMREAD, $GDIP_PXF32ARGB)     $pBits = DllStructGetData($tData, 'Scan0')     If Not $pBits Then Return 0     $tBIHDR = DllStructCreate('dword;long;long;ushort;ushort;dword;dword;long;long;dword;dword')     DllStructSetData($tBIHDR, 1, DllStructGetSize($tBIHDR))     DllStructSetData($tBIHDR, 2, $Ret[2])     DllStructSetData($tBIHDR, 3, $Ret[3])     DllStructSetData($tBIHDR, 4, 1)     DllStructSetData($tBIHDR, 5, 32)     DllStructSetData($tBIHDR, 6, 0)     $hResult = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBIHDR), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'dword', 0)     If (Not @error) And ($hResult[0]) Then         DllCall('gdi32.dll', 'dword', 'SetBitmapBits', 'ptr', $hResult[0], 'dword', $Ret[2] * $Ret[3] * 4, 'ptr', DllStructGetData($tData, 'Scan0'))         $hResult = $hResult[0]     Else         $hResult = 0     EndIf     _GDIPlus_BitmapUnlockBits($hBitmap, $tData)     Return $hResult EndFunc   ;==>_GDIPlus_BitmapCreateDIBFromBitmap ;The GetPixel method gets the color of a specified pixel in this bitmap. ;GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y, ARGB *color) ; Func _GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY)     Local $tArgb, $pArgb, $aRet     $tArgb = DllStructCreate("dword Argb")     $pArgb = DllStructGetPtr($tArgb)     $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapGetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "ptr", $pArgb)     Return "#" & Hex(DllStructGetData($tArgb, "Argb"), 6) EndFunc

Any idea what's goin' on and how I can fix it?
Thanks

Viewing all articles
Browse latest Browse all 12506

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>