IrfanView To Clipboard, GetPixelColor With No Focus Change

Technical support and scripting issues

Moderators: JRL, Dorian (MJT support)

Post Reply
NickD
Pro Scripter
Posts: 58
Joined: Fri Sep 23, 2016 2:17 pm

IrfanView To Clipboard, GetPixelColor With No Focus Change

Post by NickD » Tue Nov 01, 2016 12:21 pm

Hi,

I am currently using:
Run>C:\Program Files\IrfanView\i_view64.exe /capture=0
to capture my haystack and analyse cursor color.

This code captures to clipboard and opens the image in full screen (via IrfanView, my chosen .BMP default).
After using GetPixelColor on the clipboard haystack, I then use:
Run>C:\Program Files\IrfanView\i_view64.exe /killmesoftly
(/killmesoftly is an IrfanView Commandline to close all IrfanView windows)
To close the clipboard before returning to the originally focused window, trigger some actions based on the pixel color results, and then loop.

I would love to know if its possible to GetPixelColor from the IrfanView snapshot without having it open in a second window, so the main window could be continually focused which the script is running. Any ideas?

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

Re: IrfanView To Clipboard, GetPixelColor With No Focus Chan

Post by JRL » Tue Nov 01, 2016 2:13 pm

Use FindImagePos> rather than GetPixelColor>.

Create a one pixel BMP the color that you are looking for and use that as the Needle file. Create the haystack file just as you are doing it now. Assuming needle and haystack are named that and are located in your temp folder, use the line

Code: Select all

FindImagePos>%temp_dir%needle.bmp,%temp_dir%stack.bmp,1,1,Xpos,Ypos,numfound,EXACT
Then, rather than looking in a particular position on the haystack file for a pixel color as you do with GetPixelColor>, you would look at the acquired x and y locations where the needle file was found and determine if one or more of those locations match your criteria.

NickD
Pro Scripter
Posts: 58
Joined: Fri Sep 23, 2016 2:17 pm

Re: IrfanView To Clipboard, GetPixelColor With No Focus Chan

Post by NickD » Tue Nov 01, 2016 3:35 pm

Thanks JRL,

That's really helpful.
Whats the fastest WSI_TIMEOUT you would use, given that its only looking for 1 pixel, in co'ords of 1 pixel square?

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

Re: IrfanView To Clipboard, GetPixelColor With No Focus Chan

Post by JRL » Tue Nov 01, 2016 4:41 pm

...its only looking for 1 pixel, in co'ords of 1 pixel square?
So are you taking a one pixel screen capture? If so, FindImagePos> will be amazingly fast. FindImagePos> will find 3000 one pixel images from a BMP of my 1920 x 1080 screen in about 50 miliseconds.

But I don't see how anything in this thread so far applies to WaitScreenImage> thus WSI_Timeout?

NickD
Pro Scripter
Posts: 58
Joined: Fri Sep 23, 2016 2:17 pm

Re: IrfanView To Clipboard, GetPixelColor With No Focus Chan

Post by NickD » Tue Nov 01, 2016 6:08 pm

Yes, sorry, silly question, I somehow assumed that WSI_TIMEOUT applied to FindIMagePos, but if the haystack doesn't contain an image, not much sense in waiting lol.

I have added your code to my macro and it's running plenty fast enough :D
I actually had to slow it down a touch because IrfanView could not keep up with writing the screenshot to file in time to overwrite it.

If I want to check for three states, with each of the three states being a trigger, and a trigger for a fourth undefined state, is there a more efficient approach with FindImagePos than the flag method as shown below?

Let>flag=undefined
FindImagePos>%temp_dir%greenneedle.bmp,%temp_dir%stack.bmp,1,1,Xpos,Ypos,numfound,EXACT
if>NumFound>0
Let>flag=green
Endif

FindImagePos>%temp_dir%redneedle.bmp,%temp_dir%stack.bmp,1,1,Xpos,Ypos,numfound,EXACT
if>NumFound>0
Let>flag=red
Endif

FindImagePos>%temp_dir%amberneedle.bmp,%temp_dir%stack.bmp,1,1,Xpos,Ypos,numfound,EXACT
if>NumFound>0
Let>flag=amber
Endif

If>flag=green
Goto>Dothis
Esle
If>flag=red
Goto>Dothis
Esle
If>flag=amber
Goto>Dothis
Esle
If>flag=undefined
Goto>Dothis
Endif
Endif
Endif
Endif

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

Re: IrfanView To Clipboard, GetPixelColor With No Focus Chan

Post by Marcus Tettmar » Mon Nov 07, 2016 5:18 pm

I don't really see why you need a flag. E.g. assuming I've understood your logic correctly, you might just want this:

Code: Select all

FindImagePos>%temp_dir%greenneedle.bmp,%temp_dir%stack.bmp,1,1,Xpos,Ypos,numfound,EXACT
if>NumFound>0
  Gosub>DoThis
Else
  FindImagePos>%temp_dir%redneedle.bmp,%temp_dir%stack.bmp,1,1,Xpos,Ypos,numfound,EXACT
  if>NumFound>0
    Gosub>DoThis
  Else
    FindImagePos>%temp_dir%amberneedle.bmp,%temp_dir%stack.bmp,1,1,Xpos,Ypos,numfound,EXACT
    If>NumFound>0
      Gosub>DoThis
    Else
      Gosub>DoSomethingElse
    Endif
  Endif
Endif
I wouldn't use Goto or you'll end up with messy code to get back potentially. A gosub will return you to the correct point in the logic.

I'm assuming from your logic that you want to look for either OR and not act multiple times for a match of more than one. This will look for green but only look for red if not found and then only look for amber if red not found.

Or you could do this:

Code: Select all

FindImagePos>%temp_dir%greenneedle.bmp,%temp_dir%stack.bmp,1,1,Xpos,Ypos,GreenFound,EXACT
FindImagePos>%temp_dir%redneedle.bmp,%temp_dir%stack.bmp,1,1,Xpos,Ypos,RedFound,EXACT
FindImagePos>%temp_dir%amberneedle.bmp,%temp_dir%stack.bmp,1,1,Xpos,Ypos,AmberFound,EXACT
If>GreenFound>0
  //do  green
Else
  If>RedFound>0
    //do red
  Else
    If>AmberFound>0
      //do amber
    Else#
      //do for no match
    Endif
  Endif
Endif
It really depends how you want to check. Are you wanting to check for all at once and then decide what to do. Or check for one and only check for the other if not found. Both the above do the same thing, but what if you want to perform some action when green is found AND another action if red is ALSO found? Then you'd need to remove the If nesting.

E.g.:

Code: Select all

FindImagePos>%temp_dir%greenneedle.bmp,%temp_dir%stack.bmp,1,1,Xpos,Ypos,GreenFound,EXACT
FindImagePos>%temp_dir%redneedle.bmp,%temp_dir%stack.bmp,1,1,Xpos,Ypos,RedFound,EXACT
FindImagePos>%temp_dir%amberneedle.bmp,%temp_dir%stack.bmp,1,1,Xpos,Ypos,AmberFound,EXACT
Let>AnyFound={%GreenFound%+%RedFound%+%AmberFound%}
If>AnyFound>0
  If>GreenFound>0
    //do  green
  Endif
  If>RedFound>0
    //do red
  Endif
  If>AmberFound>0
    //do amber
  Endif
Else
 //do nothing was found
Endif
I.e. in this case we might peform all three chunks of code, if all three colours were found. But we'd perform "//do nothing was found if none were found". This isn't the only way to structure it of course.

So it all depends what you really want to do. But bottom line is set your logical conditions however you want based on what your rules are.

If the code you posted correctly demonstrates the rules you are intending then either of the first two will do the same thing, but are a bit shorter. Neither is necessarily more "efficient" although I'd say using GoSub or nested code is more efficient and less messy than Gotos.
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar

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

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