FindText tutorial

Helpful script writing tricks and HowTo's
Ralf_Reddings200244
Posts: 110
Joined: 11 Mar 2023, 14:16

Re: FindText tutorial

Post by Ralf_Reddings200244 » 25 Jan 2024, 11:23

@Descolada

Your example for FindText().PixelSearch() in the tutorial, you show that its possible to search for multiple colours in one invocation of FindText:

Code: Select all

ok := FindText().PixelSearch(,,,,,, "0xFFFFFF|0x000000") ; FFFFFF = black, 000000 = white
FindText().MouseTip(ok[1].x, ok[1].y) ; Displays first found black or white pixel
I was able to get this work on my end but I would like to assign a name/comment to each colour so that I can know what coordinate is associated with a colour by the ID value. Similar to how you can do the following for graphics:

Code: Select all

FindText(X, Y, 33-150000, 137-150000, 33+150000, 137+150000, 0, 0, "|<SaveButton>[i]150$38.0000008|<LoadButton>[/i]138$39.0000D004")
But the above text graphic notation does not seem to work for me FindText().PixelSearch():

Code: Select all

CoordMode, mouse, screen
CoordMode, Pixel, Screen
;ok := FindText().PixelSearch(,,10,10,100,100,"0x00FF00|0xFF0000",,,1)     				;0x00FF00 = green | 0xFF0000 = red
ok := FindText().PixelSearch(,,10,10,100,100,"<green>0x00FF00|<red>0xFF0000",,,1) 		;0x00FF00 = green | 0xFF0000 = red
The commented out third line works but the last line does not work. I get nothing returned. I tried just "<green>0x00FF00|0xFF0000 which partially seems to work but then every found colour's ID is "green"

I cant seem to figure out where I am going wrong. I would appreciate any help

Descolada
Posts: 1204
Joined: 23 Dec 2021, 02:30

Re: FindText tutorial

Post by Descolada » 25 Jan 2024, 13:31

@Ralf_Reddings200244 PixelSearch doesn't support that syntax. However, it internally uses regular FindText with MultiColor mode, so you can actually use this instead: ok := FindText(,,,,,,0,0,"|<green>##0$0/0/00FF00|<red>##0$0/0/FF0000",,0)

Ralf_Reddings200244
Posts: 110
Joined: 11 Mar 2023, 14:16

Re: FindText tutorial

Post by Ralf_Reddings200244 » 27 Jan 2024, 11:34

@Descolada

Very interesting. Aside from the working solution, what is actually happenning internally is very good information to know. Thank you.

Gary-Atlan82
Posts: 74
Joined: 07 Mar 2023, 05:20

Re: FindText tutorial

Post by Gary-Atlan82 » 18 Feb 2024, 18:17

@Descolada

If I may ask you, do you know if its possible with FindText to query what colour a certain pixel is?
For example by providing the screen coordinates for the pixel as input and Findtext returning the pixels colour as hex code, (a value similar to what is in the AHK spy tool)

A few of the graphic design programmes I use make it a pain to acquire the hex code for the foreground/background colours, moreover I would like to do it in Findtext and take advantage of its bind window feature, so that I can get the pixel colours for even obscured windows.

Looking at the FindText GUI I have not been able to find anything.

Image

Descolada
Posts: 1204
Joined: 23 Dec 2021, 02:30

Re: FindText tutorial

Post by Descolada » 19 Feb 2024, 00:22

@Gary-Atlan82 AFAIK there isn't a dedicated function to do that, but you can use PixelSearch or PixelCount to achieve the same result:

Code: Select all

out := FindText().PixelCount(x:=100, y:=250, x, y, "FFFFFF")
MsgBox % "The color at screen coordinates (100, 250) is " (out ? "" : "not ") "white."

Gary-Atlan82
Posts: 74
Joined: 07 Mar 2023, 05:20

Re: FindText tutorial

Post by Gary-Atlan82 » 19 Feb 2024, 09:53

Thanks for the help Descolada!

I tested your solution but am I not getting the specified coordinates pixel colour code but rather if the specified coordinates pixel colour is FFFFFF or not:

Code: Select all

CoordMode, mouse,screen
out := FindText().PixelCount(10, 10, 10, 10, "FFFFFF")
print("The color at screen coordinates (10, 10) is " (out ? "" : "not ") "white.")    ;prints ---> The color at screen coordinates (10, 10) is white.
print(out)                                                                            ;prints ---> 1
I am looking for a FindText feature that returns the specified pixels colour, similar to the native PixelGetColor command, I am opting to not use the native PixelGetColor because it has severe limitations such as the window the pixel belongs to cannot be obscured or be outside the range of the monitors display area.

Interestingly enough you mention in your tutorial:
FindText().PixelCount counts the number of pixels in the search area. Since the search area can be 1-pixel-sized then this can be used as AHKs PixelGetColor as well.
With my tests, FindText().PixelCount() seems to only return a single scalar value, unlike the other functions/methods which return a object, at least on success. Maybe I am going wrong somewhere.

Looking forward to any clarification!

Descolada
Posts: 1204
Joined: 23 Dec 2021, 02:30

Re: FindText tutorial

Post by Descolada » 19 Feb 2024, 10:14

@Gary-Atlan82 sorry, the tutorial had a mistake - PixelCount isn't a replacement for PixelGetColor, but it could possibly be used to replace it. Eg if you are looking for a certain color or a range of colors.

But I misread your first question: I don't know of a way to get the color of a certain pixel (rather than check whether a pixel is of a certain color). Perhaps @feiyue can weigh in on this?

Gary-Atlan82
Posts: 74
Joined: 07 Mar 2023, 05:20

Re: FindText tutorial

Post by Gary-Atlan82 » 19 Feb 2024, 10:46

@Descolada

I see, I appreciate the clarifications.

I will wait to hear from the developer themselves then.

I think I will eventually propose this feature as a feature request on the FindText release page. This is the ideal feature to have on FindText and I could think of many use cases for it.

feiyue
Posts: 357
Joined: 08 Aug 2014, 04:08

Re: FindText tutorial

Post by feiyue » 19 Feb 2024, 21:21

@Gary-Atlan82 FindText has a GetColor() function, but it requires a screenshot first. You can write a wrapper function yourself.

Code: Select all

GetColor(x, y) {
;    if (A_CoordModePixel="Window")
;        FindText().WindowToScreen(x, y, x, y)
;    else if (A_CoordModePixel="Client")
;        FindText().ClientToScreen(x, y, x, y)
    FindText().ScreenShot(x, y, x, y)  ;// x1,y1,x2,y2
    return FindText().GetColor(x, y)
}

Descolada
Posts: 1204
Joined: 23 Dec 2021, 02:30

Re: FindText tutorial

Post by Descolada » 20 Feb 2024, 00:21

@feiyue, nice, didn't know about GetColor and SetColor so I added them to the tutorial as well now. :thumbup:
I propose a small modification to your wrapper function:

Code: Select all

GetPixelColor(x, y, screenshot:=1) {
    if (A_CoordModePixel="Window")
        FindText().WindowToScreen(x, y, x, y)
    else if (A_CoordModePixel="Client")
        FindText().ClientToScreen(x, y, x, y)
    if (screenshot)
        FindText().ScreenShot(x, y, x, y)  ;// x1,y1,x2,y2
    return FindText().GetColor(x, y)
}
I have an unrelated question for you as well: what are you experiences with using FindText in multiple DPI situations? I wrote a small example here, but found that the zoomX and zoomY arguments can only be reliably used to scale UP (eg from 96 -> 144), but not DOWN (144 -> 96). Unfortunately upscaling usually leads to a lot of data loss and thus requires high error margings, so I'm wondering whether that problem could be circumvented somehow?

Gary-Atlan82
Posts: 74
Joined: 07 Mar 2023, 05:20

Re: FindText tutorial

Post by Gary-Atlan82 » 20 Feb 2024, 07:55

Amazing! I will have a go at this when I get back to my PC.
I dont know where AutoHotkey would be without you two, thank you for all your efforts!

rawskull7
Posts: 2
Joined: 09 Oct 2022, 20:55

Re: FindText tutorial

Post by rawskull7 » 20 Mar 2024, 14:03

when using FindText.Click(), how can I add a slight delay to the click? Like I want to move the cursor to that x,y, sleep 800 ms, and then click?

Descolada
Posts: 1204
Joined: 23 Dec 2021, 02:30

Re: FindText tutorial

Post by Descolada » 21 Mar 2024, 01:14

@rawskull7, you can use regular MouseMove, Sleep, and Click:

Code: Select all

Requires Autohotkey v1

ok := FindText(...)
CoordMode, Mouse, Screen
MouseMove, % ok[1].x, % ok[1].y
Sleep 800
FindText().Click(ok[1].x, ok[1].y)

Theda
Posts: 6
Joined: 07 May 2023, 06:59

Re: FindText tutorial

Post by Theda » 19 Apr 2024, 13:42

Help me figure out the PicLib function.
if FindText().PicLib is inside the triggering part then it works.

Code: Select all

^4::
FindText().PicLib("|<test>*104$38.01zzaTk0Tztbzlrzy3zwTzztzz7wDXtXly1swMwTiCC6D7zXX1XlzkskMwT0C96D7VXUFXlsssAMwSCC76D7UEVlXVw4MwMzznzzzs",1)
if (ok := FindText(X, Y, X, Y, X + 2560, Y + 1377, 0, 0, FindText().PicLib("test"))) {
    MouseMove, X, Y + 25, 2
        Send {LButton}
}
return
work
If I move it outside the limits (I want to move it to another file), it stops working. how to create a FindText().PicLib list in another file? in the example below it does not work even in one file.

Code: Select all

FindText().PicLib("|<test>*104$38.01zzaTk0Tztbzlrzy3zwTzztzz7wDXtXly1swMwTiCC6D7zXX1XlzkskMwT0C96D7VXUFXlsssAMwSCC76D7UEVlXVw4MwMzznzzzs",1)
^4::
if (ok := FindText(X, Y, X, Y, X + 2560, Y + 1377, 0, 0, FindText().PicLib("test"))) {
    MouseMove, X, Y + 25, 2
        Send {LButton}
}
return
this not work

kashmirLZ
Posts: 56
Joined: 06 Oct 2022, 23:27

Re: FindText tutorial

Post by kashmirLZ » 20 Apr 2024, 01:11

edit: found my answer here:
viewtopic.php?p=453934#p453934

Can the FindText() function work with multiple Text-strings?
How?

I have a loop that searches for 4 variations of some text Im looking for, but maybe I can give all 4 at once to FindText? Probably would be more efficient...

Code: Select all

texts := ["|<close1>*80$47.zzzzz...zw", "|<close2>*85$51.zz...zzzU", "|<close3>*68$46.zzzz...zzy", "|<close4>*70$48.zzzz...zzU"]

; Search alternatively for up to 16 seconds
StartTime := A_TickCount

while ((A_TickCount - StartTime) < 16000) {
    for i, textX in texts {
        FindText().RangeTip(SearchX1, SearchY1, (SearchX2-SearchX1), (SearchY2-SearchY1), (A_Index & 1 ? "Red":"Blue"), 2) ; debug draw box 
        if (ok:=FindText(X:="wait", Y:=1, SearchX1, SearchY1, SearchX2, SearchY2, 0, 0, textX, ScreenShot:=1, FindAll:=0)) {
            ; If the text is found, click on it
            FindText().Click(X, Y, "L", "", 1) 
            ToolTipTimer("Clicked [x] " . i)
            FindText().RangeTip() ; debug clear box 
            return true
        }
    }
}
(sorry about the formatting of texts, there, apparently AHK can't handle an array declaration spanning multiple lines)
Last edited by kashmirLZ on 20 Apr 2024, 01:20, edited 1 time in total.

Descolada
Posts: 1204
Joined: 23 Dec 2021, 02:30

Re: FindText tutorial

Post by Descolada » 20 Apr 2024, 01:18

@kashmirLZ you can define your text as text := "|<close1>*80$47.zzzzz...zw|<close2>*85$51.zz...zzzU|<close3>*68$46.zzzz...zzy|<close4>*70$48.zzzz...zzU" and if you use FindText with it then it will match any of the variations.

kashmirLZ
Posts: 56
Joined: 06 Oct 2022, 23:27

Re: FindText tutorial

Post by kashmirLZ » 23 Apr 2024, 01:02

How might I click at an offset (rather than dead-center) from where it finds the image/text?

Descolada
Posts: 1204
Joined: 23 Dec 2021, 02:30

Re: FindText tutorial

Post by Descolada » 23 Apr 2024, 13:18

@kashmirLZ just add some value to one/both of the coordinates, eg FindText().Click(X + 100, Y) offsets 100 pixels to the right.

kashmirLZ
Posts: 56
Joined: 06 Oct 2022, 23:27

Re: FindText tutorial

Post by kashmirLZ » 25 Apr 2024, 21:27

Then i have to do math :(

rockitdontstopit
Posts: 107
Joined: 12 Nov 2022, 15:47

Re: FindText tutorial

Post by rockitdontstopit » 25 May 2024, 15:24

How does FindText solve the problem when something may or may not appear behind the image you're searching for? Currently I'm using TransN and adjusting color variations to solve this problem.

Post Reply

Return to “Tutorials (v1)”