Best way to scan for images

Hints, tips and tricks for newbies

Moderators: Dorian (MJT support), JRL

Boxxxed
Junior Coder
Posts: 26
Joined: Fri Mar 19, 2010 7:20 pm

Best way to scan for images

Post by Boxxxed » Tue Mar 23, 2010 7:31 am

For what I'm automating the positions of all images are known ahead of time. I know what the image will be, and where, time depends on the speed of the system the macro is running on. What is the fastest way to scan for these images? waitpixel doesn't work at all for some reason even though I know the exact location and colour of the pixel it will be waiting for, I've even double checked to make sure it was written properly, and also the colour code. Waitscreenimage takes a long time on slower systems, same thing for findimagepos. I just want it to wait for one small area of the screen to change to a known colour/image.

Waitpixel would seem logical there but it doesn't work at all!

Boxxxed
Junior Coder
Posts: 26
Joined: Fri Mar 19, 2010 7:20 pm

Post by Boxxxed » Tue Mar 23, 2010 1:33 pm

Getpixelcolor>113,772,CL
Messagemodal>%CL%
WaitPixelColor>8404736,113,772
Messagemodal>FOUND

I know for a fact that the colour code at the specified pixel is 8404736 from the message check and getpixelcolor. However, waitpixelcolor doesn't find it, it sits indefinitely at that command and I don't get the FOUND message even though it's the right color for the code to advance.

User avatar
JRL
Automation Wizard
Posts: 3517
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Tue Mar 23, 2010 1:41 pm

I've never used WaitPixelColor but the help for it specifies a "timeout" value on the end. Help does not indicate that the timeout is optional. If it is not optional the function may not work without it. Try adding a number for the timeout period or a zero to wait forever.

WaitPixelColor>8404736,113,772,0

Boxxxed
Junior Coder
Posts: 26
Joined: Fri Mar 19, 2010 7:20 pm

Post by Boxxxed » Tue Mar 23, 2010 2:34 pm

thanks much

Boxxxed
Junior Coder
Posts: 26
Joined: Fri Mar 19, 2010 7:20 pm

Post by Boxxxed » Tue Mar 23, 2010 4:53 pm

It's still pretty buggy as it doesn't always work, I have to wave the mouse around the pixel to get it to recognize it for some reason.

I have to use a code something like this to get it to work. Even then my confidence in this command is doubtful.

MouseMove>607,573
WaitPixelColor>13027014,607,573,0
MouseMove>607,573
RClick
MouseMove>653,682
waitpixelcolor>4210752,653,682,0
MouseMove>653,682
LClick

User avatar
Marcus Tettmar
Site Admin
Posts: 7391
Joined: Thu Sep 19, 2002 3:00 pm
Location: Dorset, UK
Contact:

Post by Marcus Tettmar » Tue Mar 23, 2010 8:12 pm

Odd. WaitPixelColor is just a loop that calls GetPixelColor. So I am afraid I am unable to explain why one works and the other doesn't unless there is some minute change within the fraction of a second between the two commands.
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar

Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?

gdyvig
Automation Wizard
Posts: 447
Joined: Fri Jun 27, 2008 7:57 pm
Location: Seattle, WA

Post by gdyvig » Wed Mar 24, 2010 3:02 pm

Does the RClick cause the color to change at 653,682?
Does the MouseMove>653,682 cause the color to change?
If so, you may need some additional Wait or WaitPixelColor commands.

Try putting a GetPixelColor immediately after these 2 commands to find out if that is happening.

You might also try GetCursorPos or WaitCursorPos so the script does not get ahead of the clicks and mousemoves.

Gale

Boxxxed
Junior Coder
Posts: 26
Joined: Fri Mar 19, 2010 7:20 pm

Post by Boxxxed » Wed Mar 24, 2010 10:23 pm

I've used a getpixelcolor loop and it seems that the colour is constantly changing back and forth between one colour and another. So any absolute scans will not work. GetRectchecksim will not work and neither will pixel scanning. Is there a way to scan for images within a certain area that I can set a colour tolerance for as well? Waitforimage is very slow when it scans the whole screen.

gdyvig
Automation Wizard
Posts: 447
Joined: Fri Jun 27, 2008 7:57 pm
Location: Seattle, WA

Post by gdyvig » Wed Mar 24, 2010 10:58 pm

You may use the GetPixelColor and check each color in a loop.
(WaitPixelColor does not work with timeouts less than 1 second)

You may also use ScreenCapture for a specified portion of the screen and FindImagePos with color tolerance in a loop.

Gale

Boxxxed
Junior Coder
Posts: 26
Joined: Fri Mar 19, 2010 7:20 pm

Post by Boxxxed » Thu Mar 25, 2010 3:02 pm

The colour changes over a gradient which I didn't realize till now so I will have to put a myriad of getpixelcolors in the loop. Will screencapture help at all? It doesn't know 'when' to take the screenshot which is what I am using the waitscreenimage for.

gdyvig
Automation Wizard
Posts: 447
Joined: Fri Jun 27, 2008 7:57 pm
Location: Seattle, WA

Post by gdyvig » Thu Mar 25, 2010 3:39 pm

FindImagePos and WaitScreenImage work well when you need to check a large number of pixels and perhaps apply a color tolerance. Using FindImagePos with a color tolerance you may be able to find your object with a small number of searches instead of a myriad of GetPixelColor searches.

WaitScreenImage requires that you scan the entire screen, which is why you may find it slow.

The ScreenCapture does not know when to take the partial screenshot. By putting ScreenCapture and FindImagePos together in a loop you have created something similar to WaitScreenImage that does not need to scan the entire screen, so it might be faster. You keep doing ScreenCaptures as rapidly as possible until you find what you are looking for.

I'm not sure how your gradient works.
It the gradient moving across the screen or the object?
Is the gradient in the background or in the object you are looking for?


Gale

Boxxxed
Junior Coder
Posts: 26
Joined: Fri Mar 19, 2010 7:20 pm

Post by Boxxxed » Thu Mar 25, 2010 5:33 pm

How exactly does FindImagePos work? Doesn't it need to scan the entire screen to find the given image? I dont see any options for making it find an image position within an area.

The gradient is a subtle change of different shades of black. I can't notice it with the naked eye but using getpixelcolor in a loop, or just the cursor tool I could see that the colour code was constantly changing for the given area.

gdyvig
Automation Wizard
Posts: 447
Joined: Fri Jun 27, 2008 7:57 pm
Location: Seattle, WA

Post by gdyvig » Thu Mar 25, 2010 5:58 pm

Here is the syntax:

FindImagePos>bitmap_to_find,bitmap_to_scan|SCREEN,color_tolerance,return_center,X_Array,Y_Array,NumFound

Note the second parameter can be bitmap_to_scan or SCREEN. If it is set to SCREEN the entire screen captured to a tempfile and then scanned. But if you provide a bitmap_to_scan bmp file you can force it to scan a much smaller screen area. Use ScreenCapture to define the scan area and create the bitmap_to_scan file.

The bitmap_to_find is a bmp file often called the needle file.
The bitmap_to_scan is a bmp file often called the haystack file.
To improve performance keep both files as small as practical.
Also try to choose a unique needle or it will find them all.

FindImagePos looks at an area in the haystack the size of the needle. It randomly selects a pixel from the needle file to see if is in the currently scanned area within the color tolerance. If it is found, it randomly selects another pixel and does the same thing up to FIP_SCANPIXEL times unless a mismatch is found. If a mismatch is found, it selects a new scanned area and repeats the process. It can find a small needle file in a haystack the size of the entire screen in a small fraction of a second.

So if each of the pixels appear to be the same color but are subtely differnent, an appropriate color tolerance will make the all appear to be the same color to FIP.

Try FIP, you will probably find the performance to be more than adequate.




Gale

Boxxxed
Junior Coder
Posts: 26
Joined: Fri Mar 19, 2010 7:20 pm

Post by Boxxxed » Thu Mar 25, 2010 10:50 pm

Label>Waitt
ScreenCapture>589,531,719,688,%SCRIPT_DIR%\CEx.bmp
FindImagePos>%SCRIPT_DIR%\CExact.bmp,CEx.bmp,40,0,Q,W,NumFoundxx
If>NumFoundxxWaitt
else
endif
------------------------------------
Doesn't work, macro sits there unable to find the image.

I want it to find CExact.bmp which is located within CEx.bmp

gdyvig
Automation Wizard
Posts: 447
Joined: Fri Jun 27, 2008 7:57 pm
Location: Seattle, WA

Post by gdyvig » Thu Mar 25, 2010 10:58 pm

Try:

Code: Select all

Label>Waitt 
ScreenCapture>589,531,719,688,%SCRIPT_DIR%\CEx.bmp 
FindImagePos>%SCRIPT_DIR%\CExact.bmp,%SCRIPT_DIR%\CEx.bmp,40,0,Q,W,NumFoundxx 
If>NumFoundxx<1,Waitt 
else 
endif 


Gale

Post Reply
Sign up to our newsletter for free automation tips, tricks & discounts