Jump to content

Advanced Pixel Search Library


FastFrench
 Share

What do you think of this library ?  

35 members have voted

  1. 1. What do you think about FastFind ?

    • It's really great, I can't imagine doing a script without it
    • It's of some use for me in my current scripts
    • I could use it some day
    • Looks nice, but of no use for me
    • I've tried it, but it doesnt fit my needs
    • Sounds good on the paper, but can't make it work (bug or too difficult to use it)
  2. 2. Have you tried it ?

    • Yes, I'm using it right now
    • Somewhat, I've done some testing, will surely use it later
    • I've downloaded it and just played a little with packaged demo scripts
    • I've downloaded it, but not tried it so far
    • Not downloaded it so far, but I probably will some day
    • It's of no interested for me.
  3. 3. What is missing or should be improved ?

    • It has all the features I may need about Pixels Handling
    • OK it's pretty fast, but couldn't it be faster ?
    • Too hard to use it, could you simplify usage ?
    • Some additional features would be nice to have (please explain in a message)
    • It really lacks some decent documentation (I still hope to find someone to help on that)
    • Some critical features are missing, can't use it (please explain in a message)
    • I found some minor bugs (please explain in a message)
    • I've found some serious bugs (please explain in a message)
    • I've never tried it so far, can't tell
    • It would be nice if you could provide easy access to the associated tool - FFShowPixel
    • I would like to use it other languages. Could you provide wrappers ? (please explain in a message)


Recommended Posts

  • 1 month later...

Hi,

As FFNearestPixel do not support ShadeVariation, you have to use the more complete version : FFNearestSpot.

I think the following should do about the same :

$return = FFNearestSpot( 0, 1, 0, 0, 0x3D494D, 3, true, 368 , 321 , 373 , 327) 
If IsArray($return) = True Then 
; ... action

Now, it doesn't really make sense to use FastFind if PixelSearch do the trick. Except for performance reasons, if you need to do a lot of searches with same snapshot (then you should use "false" instead of "true" on 7th param).

Edited by FastFrench
Link to comment
Share on other sites

Thx FastFrench, i know how to use FF now :)

$FFLastSnap = DllCall($FFDllHandle, "int", "SnapShot", "int", 0, "int", 0, "int", 0, "int", 0, "int", 0)

While 1


    ;$Object1 = PixelSearch ( 392 , 282 , 402 , 291 , 0x687162 , 1 )
    ;$Object1  = FFNearestSpot(1, 1, 397, 287, 0x687162 , 1 ,false)
    $Object1  = DllCall($FFDllHandle, "int", "GenericColorSearch", "int", 5, "int*", 1, "int*", 397, "int*",287, "int", 0x687162, "int", 1, "int", 0)
    If IsArray($Object1 ) = True Then
        MsgBox(1,"Info", "Found Object1")
        ExitLoop
    EndIf
    
    
    ;$Object2  = PixelSearch ( 354 , 305 , 361 , 313 , 0x4E5E63 , 1 )
    ;$Object2  = FFNearestSpot(1, 1, 359, 309, 0x4E5E63 , 1 ,false)
    $Object2  = DllCall($FFDllHandle, "int", "GenericColorSearch", "int", 1, "int*", 1, "int*", 359, "int*",309, "int", 0x4E5E63, "int", 1, "int", 0)
    If IsArray($Object2) = True Then
        MsgBox(1,"Info", "Found Object2")
        ExitLoop
    EndIf


    ;$Object3 = PixelSearch ( 384 , 266 , 390 , 277 , 0x090C0B , 1 )
    ;$Object3 = FFNearestSpot(1, 1, 389, 263, 0x090C0B , 1 ,false)
    $Object3 = DllCall($FFDllHandle, "int", "GenericColorSearch", "int", 1, "int*", 1, "int*", 389, "int*",263, "int", 0x090C0B, "int", 1, "int", 0)
    If IsArray($Object3) = True Then
        MsgBox(1,"Info", "Found Object3")
        ExitLoop
    EndIf


WEnd

But if i want use the DLLCall version instead of FFNearestSpot to find Object3. It will find Object1 with DLLCaLL!

What i did wrong ?

Edited by John81
Link to comment
Share on other sites

The AutoIt wrapper takes care of doing the SnapShot first (with SnapShotPreProcessor). If you uses direct DllCall instruction, then you need to do it explicitely as needed first.

Also, i've done a mistake in my previous answer : first parameter should be 1, not 0 (a single pixel is a 1 pixel x 1 pixel square, not a 0x0 one).

$return = FFNearestSpot( 1, 1, 0, 0, 0x3D494D, 3, true, 368 , 321 , 373 , 327) 
If IsArray($return) = True Then 
; ... action
Edited by FastFrench
Link to comment
Share on other sites

Please don't edit your former post to ask a new question, it's a bit confusing :mellow:

As your snapshot is done outside your loop, it won't reflect changes on the screen (so the loop is useless). You should put it inside the loop.

And the first part is not equivalent to the commented instructions.

;$Object1 = PixelSearch ( 392 , 282 , 402 , 291 , 0x687162 , 1 )
    ;$Object1  = FFNearestSpot(1, 1, 397, 287, 0x687162 , 1 ,false)
    $Object1  = DllCall($FFDllHandle, "int", "GenericColorSearch", "int", 5, "int*", 1, "int*", 397, "int*",287, "int", 0x687162, "int", 1, "int", 0)
    If IsArray($Object1 ) = True Then
        MsgBox(1,"Info", "Found Object1")
        ExitLoop
    EndIf
Here the first two params means that you're looking for a single pixel with the good color in a 5x5 area. So you surely have more chances to find it than in the next tries (looking for a pixel in a 1x1 area).
Link to comment
Share on other sites

Is it possible to use this to search for a small picture like an icon somewhere on the screen, similar to what _imagesearch() does? I've been following this topic since its beginning, but chances are I might just have missed the clue.

Link to comment
Share on other sites

Is it possible to use this to search for a small picture like an icon somewhere on the screen, similar to what _imagesearch() does? I've been following this topic since its beginning, but chances are I might just have missed the clue.

Nop. As you say, there is allready another dll with an Autoit wrapper that do the job. So it didn't sound very usefull for me to do it in FastFind.dll.
Link to comment
Share on other sites

Nop. As you say, there is allready another dll with an Autoit wrapper that do the job. So it didn't sound very usefull for me to do it in FastFind.dll.

The problem with _imagesearch() is it takes a new screenshot for every single thing you want to look for. It would be much more efficient if we could look for different things in the same screenshot, perhaps run multiple searches on multiple CPU cores at the same time and on the same screenshot. Speeding up the process of looking for a single item in a screenshot could also be achieved. It would require tiling a screenshot using overlapping borders and let each core handle a tile. Edited by Sven
Link to comment
Share on other sites

This is some really great stuff fastfrench but its kinda useless to me since i cant search my own bitmap handles that i extract on my own. Maybe it wouldnt be hard for you to add that feature like adding bitmap handle into snapshot?

FF cant take snapshots unless windows are active, this is why i need to handle this part on my own first.

Edited by Aktonius
Link to comment
Share on other sites

I see.

Thank you for your valuable feedback, Sven and Aktonius.

Actualy both suggestions are feasable, I just wonder how many people would be interested in such improvments ?

@Sven : You're right, it makes sense to add image search in FastFind, for when you have many images to search in the same SnapShot. Now, is it a frequent need ?

And the multi-thread stuff could also be done, but usually searches are much faster than the SnapShot (which can't probably be multi-threaded, as I suspect it would take even more time than done on a single thread). And starting threads still take some time by itself. So it could only be usefull when you need to find many pictures in the same very large snapshots (full-screen or close). How many people need to do that ?

@Aktonius : it shouldn't be too hard to do that either. Are other people interested in such feature ?

Edited by FastFrench
Link to comment
Share on other sites

FastFrench i think alot of people would be interested in that, i think someone else also mentioned this in this thread earlier. Also if you search google with keywords: autoit and something that describes this feature it shows some interest. But then up to you, i think its really good lib after all just to bad i am missing this part to use it on my own.

Link to comment
Share on other sites

@Sven : You're right, it makes sense to add image search in FastFind, for when you have many images to search in the same SnapShot. Now, is it a frequent need ?

Thank you for being open for this matter. While I can't speak for others, I regularly bump into cases where it would be of quite some benefit to be able to run up to 5 or 6 searches on the same screen. Whether trying to control a web browser other than Internet Explorer or a GUI written in .NET, the less time it takes to read status information, the better.

Incidentally, Tic and Ax over at autohotkey.com just came up with pretty much exactly what I need. While compiling the .dll works like a charm for me, porting the AHK code over to AutoIt is beyond my current capabilities. I thought I got the functions figured out, yet they produce different results and I'm at a loss as to what's going wrong.

Link to comment
Share on other sites

  • 2 weeks later...

Marvelous script, love your work. Detection is so fast, its blinding.

I've been playing around with a modified version of the demo, searching for a "blue" square - have changed colour, size of the square and everything works perfectly, however when I try to add in an exclusion rectangle, it doesn't work. I've modified the function to take a snapshot at the start and set FFNearest to use the previous snapshot (this still works perfectly), however adding FFAddExcludedArea after FFSnapshot() comes back with "0" (error), but I can't work out why.

Is there any way to further debug the exclusion range? or add to the graphical debug a way to highlight what area is being scanned (perhaps a green square around the scanned area, blue squares around any exclusion rectangles).

Lastly, does anyone have any suggestions for returning the location to "click" on a detected area? I'm scanning a window rather than full-screen, object is detected at say 200,200, but this is not the co-ordinates to click. I've been adding to this using:

ObjDetect[0] + WinGetPos[0] + 29, ObjDetect[1] + WinGetPos[1] + 3

Where 29 and 3 are the values for the height of the title bar and border down the left-hand side in Windows XP. It works, it just doesn't look nice.... :mellow:

Thanks again!

Link to comment
Share on other sites

MouseCoordMode option takes care of that.

EDIT:

Or maybe its PixelCoordMode

Its one of them

MouseCoordMode set to 2 works perfectly, many thanks!

... now just for some Exclusion testing... :mellow: What I'm trying is:

#Include <FastFind.au3>
#Include <WinAPI.au3>
AutoItSetOption("MouseCoordMode", 2)
HotKeySet("{F1}", "_CheckExcluded")

FFSnapShot()
FFAddExcludedArea(1, 1, 100, 100) ; exclude 100x100 square in the top left corner

While 1
    Sleep(10)
Wend

Func _CheckExcluded()
    $hWnd = WinGetHandle("[ACTIVE]", "")
    $MousePosition = MouseGetPos()

    $IsExcluded = FFIsExcluded($MousePosition[0], $MousePosition[1], $hWnd)
    If IsArray($IsExcluded) Then
        $ExclResult = $IsExcluded[0] & "x" & $IsExcluded[1]
    Else
        $ExclResult = $IsExcluded
    EndIf

    TrayTip("Exclusion", "Pixel at: " & $MousePosition[0] & "x" & $MousePosition[1] & @LF & "Reports: " & $ExclResult, 2000)
EndFunc

Pressing F1 comes up with a tooltop showing mouse co-ordinates, and the result from FFIsExcluded.

Edited by Steve0
Link to comment
Share on other sites

I'm also having trouble with excluded areas not working.

At one point in my script, I need to start clicking on yellow spots at the right hand side of the 800x600 program window.

FFSetWnd(WinGetHandle($WinTitle))
Opt("MouseCoordMode", 2)
Opt("PixelCoordMode", 2)

$Seen = TimerInit()
FFResetExcludedAreas()
FFAddExcludedArea( 0, 0, 599, 599 )
Do
  $spot = FFNearestSpot(8, 60, 799, 300, 0xFFFF00, 25, true)
  If Not @error Then
    $Seen = TimerInit()
    MouseClick( "left", $spot[0], $spot[1], 1, 1 )
    FileWriteLine($log, "Spot " & $spot[0] & "," & $spot[1] )
    Sleep( 100 )
  EndIf
Until @error And TimerDiff( $Seen ) > 100

I'm getting entries in my log file like this:

Spot 134,95

Why would the function ever return 134,95 when I have excluded from 0,0 to 599,599? Are the excluded area coordinates not the same as the window coordinates?

*Update* I tried Steve0's test script and I get the same result, never returns 1 from FFIsExcluded. Exclusion zones appear to be broken.

Edited by PhilHibbs
Link to comment
Share on other sites

Thank you for reporting this problem.

It looks like there is a small bug in the AutoIt wrapper for FFAddExcludedArea : the name of the function in the dll is "AddExcludedArea" and not "FFAddExcludedArea".

So, the function in FastFind.au3 should look like this :

Func FFAddExcludedArea(const $x1, const $y1, const $x2, const $y2)
local $Res = DllCall($FFDllHandle, "int", "AddExcludedArea", "int", $x1, "int", $y1, "int", $x2, "int", $y2)
if IsArray($res) Then return $res[0]
return $res
EndFunc

instead of

Func FFAddExcludedArea(const $x1, const $y1, const $x2, const $y2)
local $Res = DllCall($FFDllHandle, "int", "FFAddExcludedArea", "int", $x1, "int", $y1, "int", $x2, "int", $y2)
if IsArray($res) Then return $res[0]
return $res
EndFunc

I hope it will do the trick, thank you to confirm.

Edited by FastFrench
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...