Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

FindClick() - Click an onscreen image, and more


  • Please log in to reply
20 replies to this topic
berban
  • Members
  • 201 posts
  • Last active: Dec 11 2014 02:38 AM
  • Joined: 30 Dec 2009
Newer version here
The old version below still works, however the new version adds many new features which may be useful to you.


FindClick() - Click an onscreen image [updated 3/20/2012]



FindClick(ImageFile, Options="")


Usage: Pretty self explanatory. Call the function and it will click at the center of the image if it can find it on the screen.
^t::FindClick("MyImage") ;assign to a hotkey

If the function finds the image it returns the coordinates it clicked at in %Xcoord%,%Ycoord% format. If the image is not found it returns 0. An empty string is returned if it encounters an error.
If (Coords := FindClick("MyImage"))MsgBox, The image was found. It is centered at (%Coords%). ;will show something like (200,310)ElseMsgBox, Your image was not found!

Returned coordinates are always relative to the screen and not the window.



Parameters:
  • ImageFile: The image file to use for the ImageSearch call.
    The ImageFile param allows for some shortcuts if you format the "Custom Settings" section of the script.DefaultDirs is a newline-delimited list of directories that are considered default. If the full image path is omitted, FindClick() will look for the image in each of the ÞfaultDirs%, just like it normally looks in the working directory if a full path is omitted. (Note - it will look in the working directory before any of the ÞfaultDirs%.)
    DefaultExts is a newline-delimited list of extensions that FindClick() will try if you omit the file extension. The vast majority of ImageSearch image candidates are either png or bmp files, so you will generally be able to omit the extension, saving some characters.To illustrate this let's look at the example in the Usage section where we pass "MyImage". Let's say DefaultExts is bmp`npng and DefaultDirs is %A_Desktop%`n%A_ScriptDir% as they are by default. First, the function will look for a file named "MyImage" in the working directory. If that does not exist it will look for "MyImage.bmp" and "MyImage.png" in the working directory. If that is unsuccessful, it will try "MyImage", "MyImage.bmp", and "MyImage.png" in the desktop, etc, until it runs out of options, at which point it will display an error dialog saying that the image file cannot be found.
    The locations of the images are cached within the function so that after the first use of a file shortcut, subsequent calls of FindClick() using that file will perform just as quickly as entering a full filepath.
  • Options: A space-delimited string in which you can indicate additional options, such as you see in the GUI command’s Options parameter. More info here: http://www.autohotkey.com/forum/viewtopic.php?p=483397. See below in the code to find the default values for each option.
  • m - SendMode: The send mode (or first letter thereof) to use for clicks, i.e. Input, Play, or Event. Specify ControlClick (or c) to use a controlclick instead of a simulated keystroke. If m is blank or the letter d (for default), the current SendMode will be used.
  • x - X Offset: Offset from the center of the image to apply to the x-coordinate before clicking. To use the upper-left corner of the image instead of the center, specify an empty g option. The x and y values will be factored into the returned coordinate pairs.
  • y - Y Offset: Same as above for the y-coordinate.
  • o - ImageSearch Options: Optional parameters for ImageSearch, as shown in documentation. Use a comma to separate options. You may omit the asterisk (*). For example: oTransBlack,20 makes black transparent and allows 20 shades of variation.
  • n - Number of Clicks/No Click: The number of times to click on each image. Indicate 0 (the default) to do no clicking whatsoever and just return the coordinates of the found image(s). (In this sense, specifying just n is like saying "no clicking".) Without clicks, the m, d, and k options are irrelevant; however, the x and y values will still be added to the output coordinates. Leaving k blank has the same effect.
  • d - Delay: Milliseconds to sleep between each click if n > 1 or e and multiple images found.
  • k - Keystroke(s): Key to send, in Send format, e.g. {LButton Down}. Can include multiple keypresses and even non-mouse keys, for instance, {Space}. If ControlClick is in effect the format is different (see the ControlClick documentation) and a left click will be assumed if an incorrect k is given.
  • a - Active Window Only: Will only imagesearch the active window, which improves performance. Normally the function searches the entire screen.
    Note: The "entire screen" default does not count extra monitors. To search these as well, use the s option - for instance s,,+2000 will expand the search 2000px into a monitor joined to the right edge of the screen.
  • e - Every Image: Will find & click EVERY instance found. The value of e signifies the number of pixels to move downwards in the x-axis with each consecutive search. Indicate any non-numeric character to use the image height for the value of e, which may help avoid duplicate matches in a relatively homogenous region. Each instance found will be returned in a newline (`n) delimited string of coordinate pairs, for instance, 10,20`n30,40 if two are found. This behavior is not the default because it makes searching for a single image slower.
  • s - Search Within: Region within which to search for the image. Indicate either of the following:1) A comma-delimited list in the format x1,y1,x2,y2 for the top left and bottom right corners of the rectangle. List items may be blank or absent to leave that value unchanged. Coordinates are relative to the window if the a option is true. For x2 and y2, use +/- to indicate a change to the normal endpoint (depending on a, either the edge of the screen or active window). For instance, s,,-300 will search the entire screen (or window) except for the last 300 pixels of the right side.
    2) The letter m and then a number to search a square region centered at the cursor position and with a width and height twice that number. The position is saved upon calling the function and will not change if you move the mouse while searching.
  • w - Wait: If the image is not found, the function will wait this many milliseconds for it to appear before returning a blank string. You may add a comma and then a second number which indicates the delay in milliseconds between subsequent imagesearches. For example 2000,50 means the function will look for the image every 50ms until either the image is found or 2000ms elapse, for a maximum of 40 imagesearch operations. This delay will be 1/12th of the total wait time if omitted.
  • g - GUI: The number (or name in AutoHotkey_L) of the gui that will be briefly created to find the size of the input image. Leave blank to skip the size check altogether; this will force the function to use the upper left corner of the image instead of the center.[/list][/list]


    Why use FindClick()?
  • Incorporates almost all uses of the ImageSearch command into one easy-to-use function.
  • Create reliable macros for tricky applications with one short line of code.
  • Shortcuts help you avoid typing long filenames.
  • Error dialogs so you know when it's not working.

    Some working examples:
    ;----------------------------------------------------------------------------------------------------;Automatically turns off annoying ads and annotations on YouTube.com.;Example images: [url=http://www.autohotkey.net/~berban/FindClick/findclick1.png]http://www.autohotkey.net/~berban/FindClick/findclick1.png[/url]SetTimer, YouTube, 1000 ;check on a regular intervalSetTitleMatchMode, 2 ;so the below WinActive() call can match any YouTube videoReturnYouTube:If WinActive(" - YouTube") ;an imagesearch takes a fair amount of processing power, so we only want to call it with reasonable expectations of success - in this case, only if a YouTube window is activeFindClick("youtube_annotations", "a"), FindClick("youtube_x", "a") ;clicks if the images exist. Only searches the active window - this also saves processing power.Return;----------------------------------------------------------------------------------------------------;Allows you to cycle through tabs in freenode webchat. Pressing #Tab will move one tab to the right, unless you're at the last tab in which case it will return to the first tab. Tested in Chrome and IE9;Example images: [url=http://www.autohotkey.net/~berban/FindClick/findclick2.png]http://www.autohotkey.net/~berban/FindClick/findclick2.png[/url];Note how neither of the image clippings shown in the above screenshot are where the function will ultimately click. They are chosen because they are unique and do not change based on context, for instance, with the name of the tab.#IfWinActive freenode Web IRC ;needs a TitleMatchMode of 2 or RegEx#Tab:: ;neighbor of alt-tab and ctrl-tabCoords := FindClick("chat_active", "n a") ;finds the active (white) tab and stores the location without clicking (n option)StringSplit, Coords, Coords, `, ;splits the returned value into its component x- and y-coordinatesIf !FindClick("chat_inactive", "x10 s" tab1 "," tab2 - 10 "," tab1 + 50 "," tab2 + 50) ;starting to the right of where the active tab image was found, it now searches for an inactive tab, clicking on and switching to that tab if found.FindClick("chat_inactive", "a x70") ;however, if the tab is NOT found, that means that the active tab is the last (rightmost) tab. So it clicks on the first inactive tab. (x70 skips over the "Status" tab)Return#IfWinActive




    Code:
    FindClick(ImageFile, Options="") ; http://www.autohotkey.com/forum/topic77990.html{Static PrevFiles, m, x, y, o, n, d, k, a, e, s, w, g, Silent, ImageW, ImageH, LastOptions, LastImageIf (ImageFile "`n" Options <> LastOptions) {@ := 0, Commands := "m|x|y|o|n|d|k|a|e|s|w|g|Silent", Literal := """";-----------------------------------Custom Settings--------------------------------------------, DefaultExts := "png`nbmp" ; Newline (`n) delimited list of file extensions to try appending to %ImageFile% if it is still not found in ÞfaultDirs%, DefaultDirs := A_AhkPath "\..\Graphics`n" A_ScriptDir "`n" A_Desktop ; Newline (`n) delimited list of default directories to search if file not found in working directory;-----------------------------------------Options----------------------------------------------; SendMode: The send mode (or first letter thereof) to use for clicks, i.e. Input, Play, or Event. Specify ControlClick (or c) to use a controlclick instead of a simulated keystroke. If m is blank or the letter d (for default), the current SendMode will be used., m := "Input", m_def := "ControlClick", m_ver := "(?i)(?:i.*|c.*|p.*|d.*|e.*)?"; X Offset: Offset from the center of the image to apply to the x-coordinate before clicking. To use the upper-left corner of the image instead of the center, specify an empty g option. The x and y values will be factored into the returned coordinate pairs., x := 0, x_def := -10, x_ver := "(??:\+|-)?[\d.]+)?"; Y Offset: Same as above for the y-coordinate., y := 0, y_def := -10, y_ver := "(??:\+|-)?[\d.]+)?"; ImageSearch Options: Optional parameters for ImageSearch, as shown in documentation. Use a comma to separate options. You may omit the asterisk (*). For example: oTransBlack,20 makes black transparent and allows 20 shades of variation., o := "*10", o_def := "", o_ver := "(?i)\s*(?:\*?(?:Icon\d+|\d{1,3}|Trans(??:0x)?[a-f0-9]{6}|[a-z]+)|[wh](?:-1|\d+))(?(?=$)|[^\w-]+))*"; Number of Clicks/No Click: The number of times to click on each image. Indicate 0 (the default) to do no clicking whatsoever and just return the coordinates of the found image(s). (In this sense, specifying just n is like saying "no clicking".) Without clicks, the m, d, and k options are irrelevant; however, the x and y values will still be added to the output coordinates. Leaving k blank has the same effect., n := 1, n_def := 0, n_ver := "[\d.]*"; Delay: Milliseconds to sleep between each click if n > 1 or e and multiple images found., d := 10, d_def := 0, d_ver := "[\d.]+"; Keystroke(s): Key to send, in Send format, e.g. {LButton Down}. Can include multiple keypresses and even non-mouse keys, for instance, {Space}. If ControlClick is in effect the format is different (see the ControlClick documentation) and a left click will be assumed if an incorrect k is given., k := "{Click}", k_def := "{RButton}", k_ver := ""; Active Window Only: Will only imagesearch the active window, which improves performance. Normally the function searches the entire screen. Note: The "entire screen" default does not count extra monitors. To search these as well, use the s option - for instance s,,+2000 will expand the search 2000px into a monitor joined to the right edge of the screen., a := False, a_def := True, a_ver := ""; Every Image: Will find & click EVERY instance found. The value of e signifies the number of pixels to move downwards in the x-axis with each consecutive search. Indicate any non-numeric character to use the image height for the value of e, which may help avoid duplicate matches in a relatively homogenous region. Each instance found will be returned in a newline (`n) delimited string of coordinate pairs, for instance, 10,20`n30,40 if two are found. This behavior is not the default because it makes searching for a single image slower., e := "", e_def := 2, e_ver := ""; Search Within: Region within which to search for the image. Indicate either of the following: 1) A comma-delimited list in the format x1,y1,x2,y2 for the top left and bottom right corners of the rectangle. List items may be blank or absent to leave that value unchanged. Coordinates are relative to the window if the a option is true. For x2 and y2, use +/- to indicate a change to the normal endpoint (depending on a, either the edge of the screen or active window). For instance, s,,-300 will search the entire screen (or window if a is specified) except for the last 300 pixels of the right side. 2) A window handle (ID number in hexadecimal format). The script will search within that window's boundaries. 3) The letter m and then a number to search a square region centered at the cursor position and with a width and height twice that number. The position is saved upon calling the function and will not change if you move the mouse while searching., s := "", s_def := "m100", s_ver := "(?i)(?:m[\d.]*|0x[0-9A-F]+|(??:\+|-)?[\d.]*(?(?=$)|,)){0,4})"; Wait: If the image is not found, the function will wait this many milliseconds for it to appear before returning a blank string. You may add a comma and then a second number which indicates the delay in milliseconds between subsequent imagesearches. For example 2000,50 means the function will look for the image every 50ms until either the image is found or 2000ms elapse, for a maximum of 40 imagesearch operations. This delay will be 1/12th of the total wait time if omitted., w := "", w_def := "0,100", w_ver := "\d*(?:,[\d.]+)?"; GUI: The number (or name in AutoHotkey_L) of the gui that will be briefly created to find the size of the input image. Leave blank to skip the size check altogether; this will force the function to use the upper left corner of the image instead of the center., g := 98, g_def := "", g_ver := "\S*"; Silent: Instead of displaying an error dialog when an error prevents the function from executing properly (for instance, if the image file is not found), it will silently return a blank string and set the errorlevel to the error message. The errors concerned (which are numbered 1-7 in the code) should not appear during normal execution and so Silent is generally not recommended., Silent := False, Silent_def := True, Silent_ver := "";----------------------------------------------------------------------------------------------While (@ := RegExMatch(Options, "i)\s*\K(?P<O>" Commands ")(?P<V>" Literal "(?:[^" Literal "]|" Literal Literal ")*" Literal "(?= |$)|[^ ]*)", @, @ + StrLen(@O @V) + 1))If (@V <> "") {If (SubStr(@V, 1, 1) = Literal) and (StrLen(@V) > 1) and (SubStr(@V, 0, 1) = Literal) and (@V := SubStr(@V, 2, -1))StringReplace, @V, @V, %Literal%%Literal%, %Literal%, All%@O% := @V} Else%@O% := %@O%_defLoop, Parse, Commands, |If (%A_LoopField%_ver <> "") and !RegExMatch(%A_LoopField%, "^" %A_LoopField%_ver "$") {ErrorLevel := "[1]: The """ A_LoopField """ option may be incorrectly formatted.`nYou gave the following:`n" %A_LoopField% "`n" A_ThisFunc "() is looking for a match to the following regular expression:`n" %A_LoopField%_verIf !SilentMsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, %ErrorLevel%Return}Loop, Parse, PrevFiles, `n ; 1) Checks if an image's information has already been recorded, in which case the next 3 steps can be skippedIf InStr("|" A_LoopField "|", "|" ImageFile "|") {Loop, Parse, A_LoopField, |If (A_Index = 1)ImageW := A_LoopFieldElse If (A_Index = 2)Input := A_LoopFieldElse If (A_Index = 4)ImageH := # := A_LoopFieldElse If (A_LoopField <> ImageFile)Input := ImageFile, ImageFile := A_LoopFieldBreak}If !Input and !FileExist(Input := ImageFile) { ; 2) Searches for an image if a full path is not givenLoop, Parse, DefaultExts, `n, `rIf FileExist(ImageFile "." A_LoopField) and !InStr(FileExist(ImageFile "." A_LoopField), "D") {ImageFile := ImageFile "." A_LoopField, Found := TrueBreak} ElseExt%A_Index% := A_LoopFieldIf !FoundLoop, Parse, DefaultDirs, `n, `rIf FileExist(A_LoopField "\" ImageFile) and !InStr(FileExist(A_LoopField "\" ImageFile), "D") {ImageFile := A_LoopField "\" ImageFile, Found := TrueBreak} Else If DefaultExts {While (Ext%A_Index% <> "")If FileExist(A_LoopField "\" ImageFile "." Ext%A_Index%) and !InStr(FileExist(A_LoopField "\" ImageFile "." Ext%A_Index%), "D") {ImageFile := A_LoopField "\" ImageFile "." Ext%A_Index%, Found := TrueBreak}If FoundBreak}If !Found {ErrorLevel := "[2]: Image file """ ImageFile """ not found."If !SilentMsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, %ErrorLevel%Return}}If !gImageW := 0, ImageH := 0Else If (ImageW = 0) or !InStr(PrevFiles, "|" ImageFile "|") or InStr(PrevFiles "`n", "|" ImageFile "|" 0 "`n") { ; 3) Quickly builds a GUI to find the size of the imageFound := 2Gui, %g%:Add, Picture, , %ImageFile%Gui, %g%:+LastFoundControlGetPos, , , ImageW, ImageH, Static1Gui, %g%:DestroyIf (ImageW = "") {ErrorLevel := "[3]: Image file """ ImageFile """ appears to be of an unsupported filetype."If !SilentMsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, %ErrorLevel%Return}} Else If !ImageWFound := 2If (Found = 2) or !InStr(PrevFiles, "|" Input "|" ImageFile "|") { ; 4) Revisits the cache to update it or retrieve width and height valuesLoop, Parse, PrevFiles, `nIf InStr("|" A_LoopField "|", "|" ImageFile "|") {Found := 0Loop, Parse, A_LoopField, |If (A_Index = 4) and (A_LoopField > ImageH)ImageH := A_LoopFieldElse If (A_Index = 2) and (A_LoopField <> Input) {If InputFound := 3ElseInput := A_LoopField} Else If (A_Index = 1)If (ImageW > A_LoopField)Found := 3Else If (A_LoopField > ImageW)ImageW := A_LoopFieldIf (Found = 3)@ := A_LoopFieldElseFound := 0Break}If !InputInput := "?"If (Found = 3)StringReplace, PrevFiles, PrevFiles, `n%@%, `n%ImageW%|%Input%|%ImageFile%|%ImageH%Else If (Found <> 0)PrevFiles .= "`n" ImageW "|" Input "|" ImageFile "|" ImageH}If (o <> "")o := SubStr(RegExReplace(A_Space o, "[^\w-]+", " *"), 2) A_SpaceIf (e <> "") and RegExMatch(e, "\D")If !ImageH and !# {ErrorLevel := "[4]: Improper use of e (every match) param.`nEither indicate a positive integer to progress this many pixels downward before searching again, or a non-number character to use the image height. The image must have been sized by indicating a valid g parameter before using the latter option."If !SilentMsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, %ErrorLevel%Return} Elsee := ImageH ? ImageH : #LastOptions := Input "`n" Options, LastImage := ImageFile} Else ;----------------------------------------------------------------------------------------------------ImageFile := LastImageCoordMode, PixelIf a {WinGetPos, Search1, Search2, Search3, Search4, ASearch3 += Search1, Search4 += Search2} ElseSearch1 := 0, Search2 := 0, Search3 := A_ScreenWidth - 1, Search4 := A_ScreenHeight - 1If (s <> "")If (InStr(s, "m") = 1) {CoordMode, MouseMouseGetPos, MouseX, MouseYs := StrLen(s) = 1 ? 100 : SubStr(s, 2), Search1 := MouseX - s, Search2 := MouseY - s, Search3 := MouseX + s, Search4 := MouseY + s} Else If (InStr(s, "0x") = 1) {WinGetPos, Search1, Search2, Search3, Search4, ahk_id %s%If (Search1 = "") {ErrorLevel := "[5]: The window specified for the s param does not appear to exist."If !SilentMsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, %ErrorLevel%Return} ElseSearch3 += Search1, Search4 += Search2} Else {StringSplit, s, s, `,Loop 4If s%A_Index% is NumberIf (A_Index = 3)Search3 := s3 + (s3 < 0 ? Search3 : Search1)Else If (A_Index = 4)Search4 := s4 + (s4 < 0 ? Search4 : Search2)ElseSearch%A_Index% += s%A_Index%}If (w <> "") {StringSplit, w, w, `,If (w2 = "")w2 := w1 ? Floor(w1 / 12) : 100If w1w1 += A_TickCount}Loop { ; Begin the actual searchImageSearch, FoundX, FoundY, Search1, Search2, Search3, Search4, %o%%ImageFile%If !ErrorLevel {FoundX += (ImageW - 1) // 2 + x, FoundY += (ImageH - 1) // 2 + yIf (k <> "") and n {If e and ResultsSleep dIf (SubStr(m, 1, 1) <> "c") {If !Results {CoordMode, MouseMouseDelay := A_MouseDelaySetMouseDelay, -1MouseGetPos, MouseX, MouseY}MouseMove, FoundX, FoundY, 0} Else {If !Results {ControlDelay := A_ControlDelaySetControlDelay, -1DetectHiddenWindows := A_DetectHiddenWindowsDetectHiddenWindows, OffIf !InStr(",LEFT,RIGHT,MIDDLE,L,R,M,X1,X2,WheelUp,WU,WheelDown,WD,WheelLeft,WL,WheelRight,WR,", "," k ",")k := "LEFT"}WinGet, WinList, ListLoop %WinList% {WinGetPos, wx, wy, ww, wh, % "ahk_id " WinList%A_Index%If (FoundX >= wx) and (FoundY >= wy) and (FoundX <= wx + ww) and (FoundY <= wy + wh) {Window := WinList%A_Index%WinGetPos, ClickX, ClickY, , , ahk_id %Window%Break} Else If (A_Index = WinList) {ErrorLevel := "[6]: FindClick() was unable to locate a window to use for a ControlClick keystroke."If !SilentMsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, %ErrorLevel%Return}}}Loop % n * 2 - 1If !(A_Index & 1)Sleep dElse If (SubStr(m, 1, 1) = "i")SendInput %k%Else If (SubStr(m, 1, 1) = "c")ControlClick, % "x" FoundX - ClickX " y" FoundY - ClickY, ahk_id %Window%, , %k%, , NAElse If (SubStr(m, 1, 1) = "p")SendPlay %k%Else If (SubStr(m, 1, 1) = "e")SendEvent %k%ElseSend %k%}Results .= "`n" FoundX "," FoundYIf !eBreakSearch2 := FoundY + e} Else If (ErrorLevel = 2) {Loop, Parse, PrevFiles, `nIf InStr("|" A_LoopField "|", "|" ImageFile "|") {StringReplace, PrevFiles, PrevFiles, `n%A_LoopField%Return FindClick(Input, Options)}ErrorLevel := "[7]: AutoHotkey was unable to use the image """ ImageFile """ for searching."If !SilentMsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, %ErrorLevel%Return} Else If (w = "")BreakElse If Results or (w1 and (A_TickCount > w1))BreakElse If w2Sleep w2}If Results and (k <> "") and nIf (InStr(m, "c") = 1) {SetControlDelay, %ControlDelay%DetectHiddenWindows, ÞtectHiddenWindows%} Else {MouseMove, MouseX, MouseY, 0SetMouseDelay, %MouseDelay%}Return Results ? SubStr(Results, 2) : False, ErrorLevel := False}




    Notes:
  • If you need more information about how to include a function like this in your script, see Functions
  • ControlClick (m option) is useful if you do not want to interrupt use of the mouse; however, I have generally found that it is less reliable than any other method and because of this I rarely use it. Also, there is really no reason not to use a normal click keystroke - the function clicks and returns the mouse so quickly that the click is almost invisible.
  • As Chris mentions in the AutoHotkey documentation, it is almost always better to use a smaller image for imagesearch. There is almost never any need to use an image larger than 10x10 pixels, and smaller than that is even better.
  • As you can see with the 2nd example script, using imagesearch to the fullest of its potential can take some creativity. Try to find the most unique yet invariable screen area proximate to where you want to click, and then use x+/- and y+/- to reach your ultimate target.
  • The e option (click on all instances) is not perfect and might not find two images that are at the same y-coordinate. But 98% of the time it should work as expected. It would take a good deal of coding to sort this problem out fully, and I did not want to spend too much time on that.
  • You might want to change up the initial settings of the function: most notably, you may want to turn a on by default and have m assume ControlClick. This can be done easily, as shown below:
    , m := [color=red]"ControlClick"[/color], m_def := "Input" ; ControlClick is now the starting value; ..., a := [color=red]True[/color], a_def := False ; Only search active window is now the starting value
  • This function (as well as all my other scripts) is hereby licensed under the WTFPL happy.png
    ~ Created with Quick Functions for Forums by berban ~


  • Guests
  • Last active:
  • Joined: --

hey

Hi :D

berban_
  • Members
  • 202 posts
  • Last active: Aug 05 2014 11:52 PM
  • Joined: 16 Mar 2011
All done! woo. No longer a WIP!

Please let me know if you find bugs! :)

  • Guests
  • Last active:
  • Joined: --
awesome ..can i use this to click in the background firefox window..a page loaded in firefox in the background?

jpjazzy
  • Members
  • 800 posts
  • Last active: Dec 17 2014 07:22 AM
  • Joined: 16 Feb 2010
This is more refined version of an image search with purpose.

The region to be searched must be visible; in other words, it is not possible to search a region of a window hidden behind another window. By contrast, images that lie partially beneath the mouse cursor can usually be detected. The exception to this is game cursors, which in most cases will obstruct any images beneath them.


In other words, no.

berban_
  • Members
  • 202 posts
  • Last active: Aug 05 2014 11:52 PM
  • Joined: 16 Mar 2011
You can use it to click on a non-active window if you use the ControlClick option. But the image you are searching for must still be visible on the screen.

widow
  • Guests
  • Last active:
  • Joined: --
you can move the window away from the screen

ip0t
  • Guests
  • Last active:
  • Joined: --
what is the same image is found more than once?

jpjazzy
  • Members
  • 800 posts
  • Last active: Dec 17 2014 07:22 AM
  • Joined: 16 Feb 2010

d - Milliseconds to sleep between each click if n > 1 or multiple images found.



berban_
  • Members
  • 202 posts
  • Last active: Aug 05 2014 11:52 PM
  • Joined: 16 Mar 2011

d - Milliseconds to sleep between each click if n > 1 or multiple images found.


Well actually that's not the full story; you also need to use the e option. This is kinda confusing and I suppose it bears some clarification.
[*:2blnxqtb]Without e (the default): The function will perform one imagesearch (unless w is specified) and only one image will be found. AutoHotkey's imagesearch works downwards by rows, so the topmost image will be clicked on, and then the function will exit and return those coords.[*:2blnxqtb]With e: The function will keep imagesearching until no images are found. It will find and click on each all images almost instantaneously, unless the d option is used to slow this down.If you want to do something else, like clicking on the first image twice and the rest once, or only clicking on the top two images, you'll have to do multiple calls of FindClick() without the e option. You'll probably also need to change the search area with the s option, otherwise the function will find the top image every new time that you call it. See the 2nd sample code (freenode tabbing) for a small example of how this might be done.

Let me know if you still have questions :)

Grendahl
  • Members
  • 416 posts
  • Last active: Jul 07 2014 08:01 PM
  • Joined: 10 Aug 2009
Instead of just clicking the center of the image... click within an offset of the center of the image. (Uses FindClick and Rnd functions together)

FindClick("image.bmp", "x" Rnd(-5, 5) " y" Rnd(-5, 5)) ; clicks within +-5 of center of image.bmp for x and y

;Rnd() ; - A Rndom float between 0.0 and 1.0 (many uses)
;Rnd(6) ; - A Rndom integer between 1 and 6 (die roll)
;Rnd("") ; - New Rndom seed (selected Rndomly)
;Rnd("", 12345) ; - New Rndom seed (set explicitly)
;Rnd(50, 100) ; - Rndom integer between 50 and 100 (typical use)

Rnd( a=0.0, b=1 ){
   IfEqual,a,,Random,,% r := b = 1 ? Rnd(0,0xFFFFFFFF) : b
   Else Random,r,a,b
   Return r
}

Thank you for the excellent function, berban!!!

(Be nice to have an /R{Xoffset:Yoffset} option in your FindCLick function for doing this too!)

  • Guests
  • Last active:
  • Joined: --

All done! woo. No longer a WIP!

Please let me know if you find bugs! :)


Well, is it possible that it won't work if the image is too large? I'm using some images whose one dimension must exceed 90 pixels. In some of them, the other dimension is only 10 px, but a couple of them are 90x90. I tried just writing
F8::FindClick("image.png")
. Turned the script on and pressed F8. I didn't see any resulting action.

Amelius
  • Members
  • 24 posts
  • Last active: Nov 11 2013 09:39 PM
  • Joined: 02 Jul 2011
I tried your script and I need some help. Does your script work with flash games? I need it for a game called RamaCity. Heres a picture of what I want it to click on-IMAGE

Here's the code I put.
!d::FindClick("population.png", "e")

When I press the hotkey nothing happens. What am I doing wrong?

LarryC
  • Guests
  • Last active:
  • Joined: --
I have dismissed any topic or readings of ImageSearch out of hand, because it seems that any script using an image captured on my home computer's monitor may not work on my gf's laptop or work computer. But maybe I am wrong? Maybe the monitor has nothing to do with it? It is not possible to find out because the other computers should not be used for my testing purposes.

berban_
  • Members
  • 202 posts
  • Last active: Aug 05 2014 11:52 PM
  • Joined: 16 Mar 2011
Amelius: I spoke to you earlier on chat today, an extra bit of advice that may be useful to everyone is to use the function's returned value for diagnostics.
!d::ToolTip, % "Image found at: " FindClick("population.png", "e")
This will display a tooltip each time you press the hotkey: "Image found at: 123,456" if it's found at 123,456 and just "Image found at: " if it's not found.

LarryC: Yes you are right that imagesearch is generally less reliable in general. But there are certain ways that it can still be used safely. You just have to be smart about it. I'll give you some examples.
Some things that should generally work across systems:[*:2pb8pd7j]An image in a webpage, as long as the webpage is not zoomed.
[*:2pb8pd7j]Simple lines and gradients, such as the borders around these forum posts.Things that might NOT work across systems:[*:2pb8pd7j]Text
[*:2pb8pd7j]Buttons, scrollbars, and other visual elements
[*:2pb8pd7j]Things that depend on the theme such as title bars or the start menu.Posted ImagePosted ImagePosted Image

I also should say that I was planning on making a few updates to the script and I might as well bounce them off you guys to see if they'd make sense.[*:2pb8pd7j]Increased performance if you are searching with the same image as the last call.
[*:2pb8pd7j]Allow searching for a color as well as an image, e.g.
FindClick("Color:23FFEE")
[*:2pb8pd7j]A "diagnostic" mode where it'll indicate if the image is found and mark where it clicked.And the following two are unlikelies but I'll put them down anyway:[*:2pb8pd7j]If I have time: if the image file was not found it prompts you to take a screenshot and guides you through the process.[*:2pb8pd7j]If I can figure out how to do it: fuzzy image searching? Maybe?Also a few minor changes like Grendahl's suggestions