GDI+ ImageSearch - breaks after x-amount of uses

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

GDI+ ImageSearch - breaks after x-amount of uses

03 Aug 2014, 04:00

I wrote a function to ImageSearch a full-screen Flash window. It works, although after x-amount of uses, it breaks, specifically, the haystack can not be found. I've tried many, many different ways: static bitmap objects, starting GDI+ outside the function and not closing, not disposing, weird delays, etc. This seemed to work the best, although it still breaks, and reloading isn't an option.
 
Gdip.ahk v1.45 (also tried Gdip_All.ahk (newest version to date) with no difference in performance)
Gdip_ImageSearch() by MasterFocus (incorporated into Gdip.ahk)
 
 

Code: Select all

ImageSearchc(ByRef out1, ByRef out2, x1, y1, x2, y2, image, vari=0, trans="",direction=5){ ; Just occurred to me as I was posting, could I just use &out1 and &out2?
    ptok:=Gdip_Startup()
    imageB:=Gdip_CreateBitmapFromFile(image)
    Scrn:=Gdip_Bitmapfromscreen(x1 "|" y1 "|" x2 - x1 "|" y2 - y1)
    Errorlev:=Gdip_ImageSearch(Scrn,imageB,tempxy,0,0,0,0,vari,trans,direction)
    if(Errorlev<1)
        return 1 ; Not found or error
    out:=StrSplit(tempxy,"`,")
    out1:=out[1] + x1
    out2:=out[2] + y1
    Gdip_DisposeImage(Scrn)
    Gdip_DisposeImage(imageB)
    Gdip_Shutdown(ptok)
    return 0
}
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
User avatar
MasterFocus
Posts: 146
Joined: 01 Oct 2013, 09:47
Location: Rio de Janeiro - RJ - Brasil
Contact:

Re: GDI+ ImageSearch - breaks after x-amount of uses

06 Aug 2014, 00:19

Hi Masonjar13, thanks for you interest in Gdip_ImageSearch() and sorry for the delay.
(I've unfortunately been from the forums for a few weeks now)

Please note that you should always dispose everything (and subsequently shutdown GDIP), even if the search fails.
I fixed the code to do so, but may wanna restart your PC if you've already executed the unsafe version.

With that said, I couldn't reproduce your problem. Here's the exact test script I ran for ~3000 iterations:
(tested with AutoHotkey111500.exe)

Code: Select all

#NoEnv
ListLines, Off
SetBatchLines, -1
Process, Priority,, High
#Include GDIP.ahk
#Include Gdip_ImageSearch.ahk
StopVar := 0
Return
;=============================================================
F12::
    While ( !StopVar && !CustomImgSearch(Output1,Output2,0,0,A_ScreenWidth,A_ScreenHeight,"IMG/T-001-folder.png") )
    {
        ToolTip, % "Iteration " ( MyCounter := A_Index )
        Sleep, 100
    }
    tooltip
    MSGBOX % ( StopVar ? "Stopped by user." : "Couldn't find the needle on screen." ) "`nLast iteration: " MyCounter
ExitApp
;=============================================================
ESC:: StopVar := 1
;=============================================================
CustomImgSearch(ByRef out1, ByRef out2, x1, y1, x2, y2, image, vari=0, trans="",direction=5) {
    token := Gdip_Startup()
    needle := Gdip_CreateBitmapFromFile(image)
    haystack := Gdip_Bitmapfromscreen(x1 "|" y1 "|" x2 - x1 "|" y2 - y1)
    found := Gdip_ImageSearch(haystack,needle,tempxy,0,0,0,0,vari,trans,direction)
    if !( found < 1 ) ; if successful
    {
        out:=StrSplit(tempxy,"`,")
        out1:=out[1] + x1
        out2:=out[2] + y1
    }
    Gdip_DisposeImage(haystack)
    Gdip_DisposeImage(needle)
    Gdip_Shutdown(token)
    return ( found < 1 ) ; will return 0 for SUCCESS, 1 for FAILURE
}
Press F12 to begin. It will stop if you press ESC or if the needle cannot be found.
In my case, I left Explorer open and my test needle image was a folder icon.
Antonio França - git.io | github.com | ahk4.net | sites.google.com
Member of the AHK community since 08/Apr/2009. Moderator since mid-2012.
Need help? Please post on the forum before sending me a PM.
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: GDI+ ImageSearch - breaks after x-amount of uses

06 Aug 2014, 01:22

That was exactly the problem, I didn't notice that. I edited it slightly, since I still need the return code.

Code: Select all

ImageSearchc(ByRef out1, ByRef out2, x1, y1, x2, y2, image, vari=0, trans="",direction=5){
    ptok:=Gdip_Startup()
    imageB:=Gdip_CreateBitmapFromFile(image)
    Scrn:=Gdip_Bitmapfromscreen(x1 "|" y1 "|" x2 - x1 "|" y2 - y1)
    Errorlev:=Gdip_ImageSearch(Scrn,imageB,tempxy,0,0,0,0,vari,trans,direction)
    Gdip_DisposeImage(Scrn)
    Gdip_DisposeImage(imageB)
    Gdip_Shutdown(ptok)
    if(Errorlev > 0)
    {
        out:=StrSplit(tempxy,"`,")
        out1:=out[1] + x1
        out2:=out[2] + y1
        return 0
    }
    return 1
}
Thank you so much, MasterFocus! Can you explain why exactly they need to be disposed, though? Are they entering other unseen memory cells? I suppose I might know that if I looked through the Gdip functions, but..

There is another slight problem: when I change the search direction, the coords return with a different off-set; when using 8 where 5 is the default, it returns coords that are slightly too far right. How can I compensate for that?
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 320 guests