Jump to content

Loop over 1M numbers fails on 9964th iteration


Recommended Posts

Now we are getting somewhere, updated version, got rid of gdiplus, no more bitmapcreatefromHbitmap or bitmaplockbits. :)

Though I couldnt get screencapture_capture to work with it, need to experiment some more, so made my own. (I can only guess but I think there's something wrong with screencapture_capture function, the same problem i had earlier where I had to use bitmapclone)

;Be sure $posx and $posy is pointing at the correct spot!
Global $posx = 1718, $posy = 699, $result = "", $code[3]
;Lookup table to avoid searching
Global $digit[115] = [1,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0, _
                      0,0,0,0,0,0,0,0,0,0,6,0,0,0,3,2,0,0,0,0, _
                      0,0,0,0,0,0,0,0,9,0,0,0,0,0,8,0,0,0,0,0, _
                      0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _
                      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _
                      0,0,0,0,0,0,0,0,0,0,0,0,0,0,5]

;Instead of screencapture_capture()
    $hDDC = _WinAPI_GetDC(0)
    $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hBmp = _WinAPI_CreateCompatibleBitmap($hDDC, 34, 20)
            _WinAPI_SelectObject($hCDC, $hBmp)
            _WinAPI_BitBlt($hCDC, 0, 0, 34, 20, $hDDC, $posx, $posy, 0x00CC0020)
            _WinAPI_DeleteDC($hCDC)

    $result = Getnumber($result)

Func Getnumber($result)
    
    Local $code[3] = [0,0,0], $value = 64, $pixels = DllStructCreate('dword[680]')
    DllCall('gdi32.dll', 'dword', 'GetBitmapBits', 'ptr', $hBmp, 'dword', DllStructGetSize($pixels), 'ptr', DllStructGetPtr($pixels))

For $loop = 1 To 680 Step 102
    $code[0] += DllStructGetData($pixels, 1, $loop   ) = 4278255360 ? $value:0
    $code[1] += DllStructGetData($pixels, 1, $loop+16) = 4278255360 ? $value:0
    $code[2] += DllStructGetData($pixels, 1, $loop+32) = 4278255360 ? $value:0
    $value /= 2
Next
    Return String($digit[$code[0]]) & String($digit[$code[1]]) & String($digit[$code[2]])
EndFunc

And a runable example (needs pic from the zip earlier)

#include <GDIPlus.au3>
#include <WinAPI.au3>
HotKeySet("{ESC}", "_exit")


;Be sure $posx and $posy is pointing at the correct spot!
Global $posx = 1718, $posy = 699, $result = "", $code[3]
;Lookup table to avoid searching
Global $digit[115] = [1,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0, _
                      0,0,0,0,0,0,0,0,0,0,6,0,0,0,3,2,0,0,0,0, _
                      0,0,0,0,0,0,0,0,9,0,0,0,0,0,8,0,0,0,0,0, _
                      0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _
                      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _
                      0,0,0,0,0,0,0,0,0,0,0,0,0,0,5]
;Test section
;--------------------------------------------------------------
$gui = GUICreate("Getnumber", 640, 480, -1, -1)
       GUISetState()
       WinWaitActive($gui); <--- necessary or screencapture fails

            _GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($gui)
   $image = _GDIPlus_BitmapCreateFromFile("374.png")
            _GDIPlus_GraphicsDrawImageRect($graphics, $image, 280, 200, 136, 31)
Sleep(10); <------- necessary because drawimagerect() is too slow, script occasionally fails without
;--------------------------------------------------------------
;/Test section

$time = TimerInit()
    ;Instead of screencapture_capture()
    $hDDC = _WinAPI_GetDC(0)
    $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hBmp = _WinAPI_CreateCompatibleBitmap($hDDC, 34, 20)
            _WinAPI_SelectObject($hCDC, $capture)
            _WinAPI_BitBlt($hCDC, 0, 0, 34, 20, $hDDC, $posx, $posy, 0x00CC0020)
            _WinAPI_DeleteDC($hCDC)

$result = Getnumber($result)

Consolewrite("Result: " & $result & " Time: " & TimerDiff($time)/1000 & @crlf)

While 1
   Sleep(10)
WEnd

Func Getnumber($result)
    
    Local $code[3] = [0,0,0], $value = 64, $pixels = DllStructCreate('dword[680]')
    DllCall('gdi32.dll', 'dword', 'GetBitmapBits', 'ptr', $hBmp, 'dword', DllStructGetSize($pixels), 'ptr', DllStructGetPtr($pixels))

For $loop = 1 To 680 Step 102
    $code[0] += DllStructGetData($pixels, 1, $loop   ) = 4278255360 ? $value:0
    $code[1] += DllStructGetData($pixels, 1, $loop+16) = 4278255360 ? $value:0
    $code[2] += DllStructGetData($pixels, 1, $loop+32) = 4278255360 ? $value:0
    $value /= 2
Next
    Return String($digit[$code[0]]) & String($digit[$code[1]]) & String($digit[$code[2]])
EndFunc

Func _exit()
    _GDIPlus_Shutdown()
    Exit
 EndFunc

I guess it should be faster now, please test and report back.

/edit

Btw, if you are loading alot of images from disk then make sure they are in uncompressed .bmp format, it takes up more space on the drive but it's faster than png, doesnt have to be decompressed as png does, Atleast 5-10% faster using bmp, especially with that many pics.

Edited by Werty

Some guy's script + some other guy's script = my script!

Link to comment
Share on other sites

6 hours ago, Werty said:

Btw, if you are loading alot of images from disk then make sure they are in uncompressed .bmp format, it takes up more space on the drive but it's faster than png,

Yes, and much more advantage if one knows the "bitmap" FILE ( ! ) format? Skip the first 54 bytes (file header)  and you will find....the "pixels" aka image data pixelarray (depending on the 1/2/4/8/16/24/32 Bit per Pixel mode (see header...)). So no need to CreateBitmapFromFile() because a simple "open" file gives access to the pixel data array....

Go and get the first "line" of the bitmap (as a char-string) and search in the screenshot (transfer the screenshot-bytes into a char-array...others say "string") with StringInstr().

If the first line of the bitmap is found in the screenshot, the comparison of the next "line" in the bitmap with the next "line" in the screenshot is easy. Because the position of the text ( a char-array ist the same as a byte array) is known in the screenshot-"text", the comparison with the next "lines" is only a comparison of "text" (StringMid() is our friend) .

I have written a few example scripts with this method to find a "bitmap in a bitmap". I have to look for them at the weekend :hyper:Speed-challenge opened!:thumbsup:

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...