FindText - Capture screen image into text and then find it

Post your working scripts, libraries and tools
User avatar
Sashabot
Posts: 6
Joined: 06 Jul 2019, 14:36

Re: FindText - Capture screen image into text and then find it

13 Sep 2019, 19:57

Hello anyone reading this,

I was using FindText to search for a certain area, It was working great but I still had some problems with my code, I was wondering if anyone could help.
The area I am trying to search is 424, 915 the way I put it in was

Code: Select all

if (ok:=FindText(424, 915, A_ScreenWidth, A_ScreenHeight, 424, 915, Text))
However this still searches the whole screen, I can not figure out how to set the correct cords, I tried replacing all the values in different ways. Thank you for reading
User avatar
manehscripts
Posts: 101
Joined: 03 May 2019, 16:10

Re: FindText - Capture screen image into text and then find it

14 Sep 2019, 02:13

reluct wrote:
12 Sep 2019, 13:34
What to write there (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text, , 0)), if I want the script to work if It does not find the text?
Not:=? :oops:
Hi,

"ok" is just a variable. You can change "ok" to any name you like.
-----------------------------------------------------------
Stop to think, shut up to resist, and act to win!
gregster
Posts: 2999
Joined: 30 Sep 2013, 06:48

Re: FindText - Capture screen image into text and then find it

14 Sep 2019, 02:25

@Sashabot: You should look at the function definition and parameters again:

Code: Select all

FindText(X,Y,W,H,err0,err1,Text)
The ,424, 915 in the 5th and 6th parameter seem certainly wrong. These parameters are not coordinates or width/height in pixels and can only be between 0 and 1, afaics (see below).

https://www.autohotkey.com/boards/viewtopic.php?p=146096#p146096 wrote:the parameters of X, Y, W, H to used determine a search area
X,Y are the center point about which search was conducted (where your red box was when clicked)
W,H are the offset distance from the center defining the width and height of search area (not the red box's width and height),
W and H are hardcoded to 150000 indicating a search of the entire screen.
So, effectively the search range is (X-W, Y-H)-->(X+W, Y+H).

X, Y, W, and H are calculated for you, and generally you're going to leave them alone.
If we are searching the whole screen, why even have the options? Consider 2 appropriate matches on the screen, Findtext will return the first
one found, but you want the second. Having X,Y allows you to get close to one desired, and constraining the W or H arguments can allow for
avoiding the other match and getting the desired match.

err1 is the character "0" fault-tolerant in percentage (0-1) Default 0.
err0 is the character "_" fault-tolerant in percentage.(0-1) Default 0.
I've never used this function myself, but you should probably look at the 'detailed usage' posts that are recommended in the first post (https://www.autohotkey.com/boards/viewtopic.php?f=6&t=17834#p86796) and refer to these, if they leave any question open.
gregster
Posts: 2999
Joined: 30 Sep 2013, 06:48

Re: FindText - Capture screen image into text and then find it

14 Sep 2019, 02:46

reluct wrote:
12 Sep 2019, 13:34
What to write there (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text, , 0)), if I want the script to work if It does not find the text?
Not:=? :oops:
Try ! (which means logical NOT):

Code: Select all

if !( ok := FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text, , 0) )
; or just
if !FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text, , 0)	; if you don't need the arbitrarily named variable 'ok' later
because:
https://www.autohotkey.com/boards/viewtopic.php?f=6&t=17834#p86796 wrote:if no image is found, the function returns 0.
0 means false in boolean terms. Then, not 0 means true.
reluct
Posts: 61
Joined: 28 Nov 2018, 05:07

Re: FindText - Capture screen image into text and then find it

14 Sep 2019, 03:00

Code: Select all

if !( ok := FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text, , 0) )
Thanks it works.
Ben
Posts: 13
Joined: 03 Oct 2016, 07:26

Re: FindText - Capture screen image into text and then find it

15 Sep 2019, 20:38

@ricardo231
ricardo231 wrote:
26 Aug 2019, 15:34
@Ben if I use your code I can search the converted image on any screen without failing?
If you have a monitor to the left of your primary monitor the default code will fail.

FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text)

0,0 is the top-left coordinate of the primary monitor, so any monitor to the left has to be addressed with a negative X value.

I'm not trying to make a big deal of this, but until I realized what was happening it was a bit frustrating for me when code worked on one monitor but not another.

I created a FindText wrapper function, FindTextAW(), that will apply FindText to the active window. This improves the find speed when you have a high resolution desktop area. You can find a description and source code for it here.
Elixium
Posts: 4
Joined: 26 Oct 2018, 12:49

Re: FindText - Capture screen image into text and then find it

21 Sep 2019, 17:48

How would you use findtext to find multiple texts within a single script? e.g.
something like this.

Text:="|<>stuff"
Text2:="|<>morestuff"

if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text))
if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text2))

with the script I want to.
Find word "a" then do something, find word "b" & do something different.

I have the script working fine with single words.
Last edited by Elixium on 22 Sep 2019, 12:19, edited 2 times in total.
Elixium
Posts: 4
Joined: 26 Oct 2018, 12:49

Re: FindText - Capture screen image into text and then find it

22 Sep 2019, 03:20

Elixium wrote:
21 Sep 2019, 17:48
How would you use findtext to find multiple texts within a single script? e.g.
something like this.

Text:="|<>stuff"
Text2:="|<>morestuff"

if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text))
if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text2))

with the script I want to.
Find word "a" then do something, find word "b" & do something different.

I have the script working fine with single words.
I've figured this you simply repeat the text code like below to overwrite the value of "text" for the next bit of code that gets executed instead of trying to have a separate text2 value. Thanks to the author for this great script.

Text:="|<>stuff"
Text:="|<>morestuff"
if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text))
if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text))

:dance:
potroveio
Posts: 8
Joined: 17 Sep 2019, 13:45

Re: FindText - Capture screen image into text and then find it

29 Sep 2019, 14:45

any ideas on how to make this run on an inactive or minimized window or on virtual destkop on the background? thanks!!
RinkaDink
Posts: 30
Joined: 03 Sep 2018, 14:52
Facebook: 1982
Google: 1982

Re: FindText - Capture screen image into text and then find it

06 Oct 2019, 23:57

Dears, good morning.

Just copied the code from page 1 and getting error on the code (Parameter#2 Invalid) in row 477: GUI,ADD,TAB3
Previous versions without any problems.

Best regards
RinkaDink
User avatar
Sashabot
Posts: 6
Joined: 06 Jul 2019, 14:36

Re: FindText - Capture screen image into text and then find it

09 Oct 2019, 17:17

@gregster
If i understood it I wouldn't be asking for help...
User avatar
boiler
Posts: 2914
Joined: 21 Dec 2014, 02:44

Re: FindText - Capture screen image into text and then find it

10 Oct 2019, 07:45

RinkaDink wrote:
06 Oct 2019, 23:57
Dears, good morning.

Just copied the code from page 1 and getting error on the code (Parameter#2 Invalid) in row 477: GUI,ADD,TAB3
Previous versions without any problems.

Best regards
RinkaDink
Update to the latest version of AHK. It needs to be v1.1.23.00 or later in order to use Tab3.
User avatar
boiler
Posts: 2914
Joined: 21 Dec 2014, 02:44

Re: FindText - Capture screen image into text and then find it

10 Oct 2019, 07:56

Sashabot wrote:
13 Sep 2019, 19:57
I was using FindText to search for a certain area, It was working great but I still had some problems with my code, I was wondering if anyone could help.
The area I am trying to search is 424, 915 the way I put it in was

Code: Select all

if (ok:=FindText(424, 915, A_ScreenWidth, A_ScreenHeight, 424, 915, Text))
However this still searches the whole screen, I can not figure out how to set the correct cords, I tried replacing all the values in different ways. Thank you for reading
The 4th and 5th parameters where you have 424, 915 for a second time are supposed to be a fraction of the number 1 (such as 0.1 for 10%), so your numbers are seen as much greater than 100%. So replace 424, 915 with 0, 0 for those parameters.

Edit: Removed incorrect information.
Last edited by boiler on 11 Oct 2019, 19:54, edited 1 time in total.
User avatar
boiler
Posts: 2914
Joined: 21 Dec 2014, 02:44

Re: FindText - Capture screen image into text and then find it

10 Oct 2019, 08:04

Elixium wrote:
21 Sep 2019, 17:48
How would you use findtext to find multiple texts within a single script? e.g.
something like this.

Text:="|<>stuff"
Text2:="|<>morestuff"

if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text))
if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text2))

with the script I want to.
Find word "a" then do something, find word "b" & do something different.

I have the script working fine with single words.
You need to put blocks of text after each if statement to execute their code only if the associated text is found:

Code: Select all

Text:="|<>stuff"
Text2:="|<>morestuff"

if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text))
{
	MsgBox, % Text " was found"
	; all the code you want to execute if Text is found goes here
}
if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text2))
{
	MsgBox, % Text2 " was found"
	; all the code you want to execute if Text2 is found goes here
}
If you want it to continuously check for those pieces of text and execute the associated code over and over, then you can put it in a loop:

Code: Select all

loop
{
	if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text))
	{
		MsgBox, % Text " was found"
		; all the code you want to execute if Text is found goes here
	}
	if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text2))
	{
		MsgBox, % Text2 " was found"
		; all the code you want to execute if Text2 is found goes here
	}
}
Edit: Removed incorrect information.
Last edited by boiler on 11 Oct 2019, 19:56, edited 1 time in total.
gregster
Posts: 2999
Joined: 30 Sep 2013, 06:48

Re: FindText - Capture screen image into text and then find it

10 Oct 2019, 12:44

boiler wrote:
10 Oct 2019, 08:04
The := is an assignment operator only, and you are assigning the result to the variable ok instead of comparing it, making it always evaluate to true no matter the result of the FindText.
I think you are mistaken re the result of Findtext()

Code: Select all

if (ok:=FindText(true))		; true
	msgbox % "true: " ok

if (ok:=FindText(false))	; false
	msgbox not executed
else
	msgbox % "false: "ok

Findtext(bool){
	return bool
}
Yes, this is not suited to compare the variable ok with the result of Findtext(), but...
the if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text)) line can actually have its use. It actually comes from the codebox in the original, first post of this topic (and I guess, there it was picked up by various users):

Code: Select all

;[...]
if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text))
{
  CoordMode, Mouse
  X:=ok.1.1, Y:=ok.1.2, W:=ok.1.3, H:=ok.1.4, Comment:=ok.1.5, X+=W//2, Y+=H//2
  ; Click, `%X`%, `%Y`%
}

MsgBox, 4096, `% ok.MaxIndex(), `% "Time:``t" (A_TickCount-t1) " ms``n``n"
  . "Pos:``t[%x%, %y%]  " X ", " Y "``n``n"
  . "Result:``t" (ok ? "Success ! " Comment : "Failed !")

for i,v in ok
;[...]
As Findtext() returns an array if successful, you can do an if-check for true and an assignment of that returned array (if one is returned) to the variable ok at the same time.

In the code above, ok is not a variable that gets compared to the result of Findtext(), but a variable that gets assigned an array. Later, this variable/array is used for various things...
User avatar
boiler
Posts: 2914
Joined: 21 Dec 2014, 02:44

Re: FindText - Capture screen image into text and then find it

10 Oct 2019, 12:59

Ah, good point. Its return value is true or false. My bad.
uwscia
Posts: 1
Joined: 05 Jul 2018, 18:32

Re: FindText - Capture screen image into text and then find it

11 Oct 2019, 19:49

Just wanted to ask if the 1st post could be updated to reflect the current state of the function, having to read the whole thread is cumbersome.
And would like a better built in array for the current output of found images as described below.

FOR SINGLE IMAGE DETECTION PER CYCLE

Code: Select all

Image := "|<SINGLE_PIC_NAME>*76"
Pic(Image,1) ; <--- This function is posted in this thread not going to add it's redundant.

If (ok:=FindText(0, 35, 1200, 60, 0, 0, Image) <--- Without the use of the Pic() Function.
If (ok:=FindText(0, 35, 1200, 60, 0, 0, this.Pic("SINGLE_PIC_NAME")))
{
	TrayTip , FindText Function, Found, 5, 16 ; <--- Personally don't use MSGBOX when not needed, it traps the code.
} Else {
	TrayTip , FindText Function, No Image Found, 5, 16
}
FOR MULTI IMAGE DETECTION PER CYCLE

Code: Select all

Image :="|<MULTI_PIC_NAME1>*76"
Image .="|<MULTI_PIC_NAME2>*76"
Image .="|<MULTI_PIC_NAME3>*76"
Image .="|<MULTI_PIC_NAME4>*76"
Pic(Image,1) <---- Can be added as a single dump or 
static ID := 0
List := {}
INIREAD, INIList, FILEname
Loop, parse, INIList, 'n
{
	ID++
	INIREAD, IDvar, FILEname, %A_loopField%, ID
	INIREAD, IMAGEvar, FILEname, %A_loopField%, IMAGE
	Pic(IMAGEvar,1)
	params := {Name:A_loopField, ID:IDvar, Image:IMAGEvar, X:X, Y:Y, W:W, XW:XW, YH:YH}
	this.List[this.ID] := params
}

;ONLY ONE OPTION ABOVE IS REQUIRED JUST SHOWING DIFFERENT METHODS.

If (FOUND := FindText(0, 35, 1200, 60, 0, 0, this.Pic("MULTI_PIC_NAME1|MULTI_PIC_NAME2|MULTI_PIC_NAME3|MULTI_PIC_NAME4")))
{
	;THIS IS WERE ID LIKE THE CORE CODE TO BE UPDATED TO A BETTER ASSOCIATED ARRAY AS SHOWN ABOVE IN THE INIREAD LOOP
	;OLD ok.1+#1-5
	;CURRENT ok.1.#1-5
	Loop, % FOUND.MaxIndex() ; IF COMPARING FOUND ARRAY TO LIST ARRAY USE A_Index-1 cause arrays start at 0 and Loops default to 1
	{
		FOUND[A_Index].ID ; This is "Comment" as seen in the current code.
		FOUND[A_Index].X
		FOUND[A_Index].Y
		FOUND[A_Index].W
		FOUND[A_Index].H
		FOUND[A_Index].XW := FOUND[A_Index].X+=FOUND[A_Index].W//2
		FOUND[A_Index].YH := FOUND[A_Index].Y+=FOUND[A_Index].H//2
		;ABOVE IS JUST BROKEN OUT TO SHOW THE OUTPUTS OF THE "FOUND" ARRAY IF CORE CODE WAS REWRITTEN.
		TrayTip , FindText Function, % FOUND[A_Index].ID, 5, 16 
		If FOUND[A_Index].ID == "MULTI_PIC_NAME1"
		{
			;DO SOMETHING IF IMAGE 1 IS FOUND
		} Etc.
		;OR USED MORE DYNAMICALLY
		Parent := A_Index
		Loop, % List.MaxIndex()
		{
			If (List[A_Index-1].ID == FOUND[Parent].ID)
			{
			}
		}
	}
} Else {
	TrayTip , FindText Function, No Image Found, 5, 16
}
thebbandit
Posts: 2
Joined: 02 Jul 2019, 11:34

Re: FindText - Capture screen image into text and then find it

Yesterday, 01:01

Thank you so much for this library! Just stumbled across this and it is quite a thoroughly scripted library, you have done an amazing job on this
22chars
Posts: 1
Joined: Today, 14:54

Re: FindText - Capture screen image into text and then find it

Today, 15:12

@feiyue
@c4p

Hey guys, amazing tool & Library you created! I'm new to ahk and i'm trying to make the re-search only in a loop till the image string is found.

So basically I am waiting for the windows application loading bar to go from 0% to 100%. The image string is 100% captured. If it does not see 100% I want it to wait and re-scan it, till it sees the load bar displaying 100%. I would very strongly appreciate an response.

I read the if, else, and statements help pages on ahk already I am super confused ):

Code: Select all

t1:=A_TickCount
t1:=A_TickCount

Text:="|<100 Percent>#[email protected]$68.zzszzzzzlzzzzwzzzzzzDzzzyQ00000tzzzzC000007Dzzzb000000tzzznU000007DzztkC7Xrn0tzzws7XxzhU7Dw0Q1trvvk0s0zC06QyPg07Dzz01bDa600zzzU0NntXy07zzk06RysxU0zzs01XxyPM07zw00wyTCQ00zy0000000007zzzzzzzzzzzzzzzzzzzzzzzU"

if (ok:=FindText(0, 0, A_ScreenWidth, A_ScreenHeight, 0, 0, Text))
{
  CoordMode, Mouse
  X:=ok.1.1, Y:=ok.1.2, W:=ok.1.3, H:=ok.1.4, Comment:=ok.1.5, X+=W//2, Y+=H//2
  ; Click, %X%, %Y%
}

for i,v in ok
  if i>2 and i=err1, err0
      TrayTip, Checker, Awaiting Session Start.

else if i<=2 and not i=err1, err0
      TrayTip, Checker, Session has started. 

Return to “Scripts and Functions”

Who is online

Users browsing this forum: JoeWinograd, SpeedMaster and 64 guests