Jump to content
zippoxer

Saving a screenshot as bitmap

Recommended Posts

In a virtual machine, every screenshot takes much more time than in a native machine.

My script executes FindColor 120 times to read a progress bar and if I'm right, it makes SCAR take 120 screenshots, which is the right move, but inefficient in a virtual machine.

One solution is to take a screenshot, execute FindColor 120 times on it and then free it.

Can I do that in SCAR? if yes, how then?

 

Thanks in advance.

Link to comment
Share on other sites

Technically this is "not" possible. However, it would take less time for the system to get the image if it were an image that's already in the memory rather than blitting from the screen. You can create a screenshot and then use that as target. SCAR will still make copies of that image to analyze, but it will take a lot less time to do so. The changes I'm going to make to the client system in SCAR 3.50 will also make this process easier and give you more options.

 

Here's an example:

  // ...
 GetClientDimensions(w, h);
 b := BitmapFromString(w, h, '');
 CopyClientToBitmap(b, 0, 0, w - 1, h - 1);
 SetTargetBitmap(b);
 // Search here!
 ResetDc;
 FreeBitmap(b);
 // ...

 

This demonstrates that the client is returned to normal correctly:

var
 b, w, h: Integer;
begin
 WriteLn(GetTargetDC);

 GetClientDimensions(w, h);
 b := BitmapFromString(w, h, '');
 CopyClientToBitmap(b, 0, 0, w - 1, h - 1);
 SetTargetBitmap(b);

 WriteLn(GetTargetDC);

 ResetDc;
 FreeBitmap(b);

 WriteLn(GetTargetDC);
end.

 

I've also attached an example script that will show you a benchmark, remove the comment of the define to enable the bitmap targeting. For me the benchmark runs at an average/search of 53,228ms without the bitmap target and with bitmap at 4,18ms. This is for a full-hd (1920*1080) area without finding the color, so it searches the entire area.

Example_BitmapTarget.scar

Link to comment
Share on other sites

Wait, are you telling me that SCAR takes a screenshot every FindColor? It would be extremely trivial to have a bitmap type, taking a screenshot and storing it in a variable of such a type, and searching that instead.

 

An alternative to that would be caching a screenshot for 15 milliseconds or so (perhaps more, considering that we don't need that granularity), and then taking another once that is deemed 'expired'.

 

The first solution is more powerful, and may require a separate set of Find routine (I don't know if SCAR supports function overloading in the script code). The second approach can be integrated into any current Find routines easily, and I don't know if we really need the power of the first for anything.

 

Furthermore, you could make the cache expiration timer a property set for each individual script's context, allowing it to be changed as necessary, and you could make the default expiration '0' to maintain the current behavior for each script unless the script wants to use the optimized caching.

 

Edit: Just to make it clear, I would recommend the second as it is something you can push out in less than 30 minutes.

 

I assume you have a GetScreenshot method somewhere - store two variables, LastScreenshot and LastScreenshotDate, and then if more than 15 millis have elapsed since LastScreenshotDate, run the old code, otherwise return LastScreenshot.

Edited by Aftermath
Link to comment
Share on other sites

I found a strange thing right now. If the client window is activated (focused) then reading a progress bar takes 4.5 seconds, if it isn't then reading the exactly same looking progress bar takes 0.2 seconds.

Is it SCAR or VMWare making that huge difference?

Note: I was not using Freddy's method in this test.

Link to comment
Share on other sites

When a window is focused it's redrawn a lot, one of the reasons why it takes long to get the images it that it has to wait for the image to be redrawn, this has to be synchronized properly which increases the wait time. Windows that aren't focused are redrawn less often because they're usually not really active, so these would be easier to get a screenshot of.

 

Wait, are you telling me that SCAR takes a screenshot every FindColor? It would be extremely trivial to have a bitmap type, taking a screenshot and storing it in a variable of such a type, and searching that instead.

 

An alternative to that would be caching a screenshot for 15 milliseconds or so (perhaps more, considering that we don't need that granularity), and then taking another once that is deemed 'expired'.

 

The first solution is more powerful, and may require a separate set of Find routine (I don't know if SCAR supports function overloading in the script code). The second approach can be integrated into any current Find routines easily, and I don't know if we really need the power of the first for anything.

 

Furthermore, you could make the cache expiration timer a property set for each individual script's context, allowing it to be changed as necessary, and you could make the default expiration '0' to maintain the current behavior for each script unless the script wants to use the optimized caching.

 

Edit: Just to make it clear, I would recommend the second as it is something you can push out in less than 30 minutes.

 

I assume you have a GetScreenshot method somewhere - store two variables, LastScreenshot and LastScreenshotDate, and then if more than 15 millis have elapsed since LastScreenshotDate, run the old code, otherwise return LastScreenshot.

 

SCAR takes a screenshot only of the part of the screen it's searching. The current system relies on bitmap targeting to get around this bottleneck. The new client system I'm working on will cache the client image, allow a script to pause the refreshing and/or turn off caching, depending on the needs of the script. I've kept the system the way kaitnieks originally designed it to keep backwards compatibility at a maximum so far.

Edited by Freddy
Link to comment
Share on other sites

Interesting...

Is it possible to decrease the redraw frequency of a window?

 

Probably not without some hackish workaround, because other windows are outside of your process' space, which makes it very hard to influence other application due to the protection and security measures put in place by the OS.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
  • Create New...