Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows Performance Improvements #148

Open
jespertheend opened this issue Sep 13, 2019 · 10 comments
Open

Windows Performance Improvements #148

jespertheend opened this issue Sep 13, 2019 · 10 comments

Comments

@jespertheend
Copy link

Hi, I'd like to use this to capture my screen and send the average color to my hue lights so the color of the lights are synced with what is displayed on the screen. But in order for this to work, taking screenshots should be somewhat fast. So far I measured about 300ms before the screenshot() promise is resolved. This was on a somewhat decent windows PC. I was hoping to get a framerate of at least about 10fps, though 3fps should also be fine to be honest. But having a lower latency would be nice.
Is there anything that could be done to improve the performance a bit? I wanted to have a look at the code to see if I could find anything but I think most of the code is inside screenCapture_1.3.2.bat. Is the source code of this file available somewhere?

@bencevans
Copy link
Owner

Hi @jespertheend

The code that handles the functionality for Windows can be found at https://github.com/bencevans/screenshot-desktop/tree/master/lib/win32

I suspect if there's any improvements in speed it would probably be in the https://github.com/bencevans/screenshot-desktop/blob/master/lib/win32/screenCapture_1.3.2.bat file although haven't run a tests on where the performance lag actually comes from.

@jespertheend
Copy link
Author

Oh hah, for some reason I was expecting screenCapture_1.3.2.bat to be binary. I got confused with .dll files, weird.
Alright nice, I'll check it out and do some profiling.

I think the main reason for the long execution time is that the screenshot is being written to disk, then read by nodejs into memory, and then deleted. I'll try to figure out if there's a way to pipe it from the bat file to nodejs.

@bencevans
Copy link
Owner

That'd be fantastic!

@bencevans bencevans changed the title performance improvements window performance improvements May 30, 2020
@bencevans
Copy link
Owner

@G7495x I have a routine repeating every 2s. My task manager reports up to 3MB/S disk usage. Just reporting...
#161 (comment)

@bencevans bencevans changed the title window performance improvements Windows Performance Improvements May 30, 2020
@sxxov
Copy link

sxxov commented Aug 5, 2021

Would you guys be interested in a PR with a powershell based solution? I've got something written up taking about 15-20ms by piping screenshots straight through stdout.

(Powershell isn't a requirement, I'm just not well versed in .NET)

@bencevans
Copy link
Owner

That sounds like a big improvement. Yes, very interested.

@sxxov
Copy link

sxxov commented Aug 5, 2021

I looked around & noticed that #193 is in the pipeline. A big refactor to Powershell would probably not be a good idea xd. I could publish my code elsewhere & maybe others may adapt it to be used in .NET. It shouldn't be too hard as it's just a matter of piping & not corrupting binary STDOUTs. (:

EDIT: Just did some more testing. the 15-20ms figure I'd got inside powershell, but the overhead from node communication adds on top a few hundred ms (200-300). Back to the drawing board I guess xd

@Venryx
Copy link

Venryx commented Sep 5, 2021

The windows-ffi library I just put together works well for me for fast screenshot-taking. (StackOverflow post)

It uses ffi-napi to make the Windows API calls necessary to take a screenshot, and then reads from the Buffer object to retrieve the pixel data.

Here are the timings I got:

  • Full-screen (2560x1440), all windows (ie. "desktop" window): ~80ms
  • Full-screen (2560x1440), single window: ~20ms
  • Region (700x200), all windows (ie. "desktop" window): ~50ms
  • Region (700x200), single window: ~4ms

@sxxov
Copy link

sxxov commented Sep 5, 2021

If anyone's still wondering, I've developed my research into a full package available from npm/githubwindows-ss. It uses edge-js & C# (managed to learn it, was surprisingly pleasant) to access win32 API's.

It's ever so slightly faster than your suggestion @Venryx. Performance metrics taken from my own testing (excerpt from README):

Using this repo. The numbers below were taken over 1000 runs, each at 2560x1440*, outputing bmp.

Library Save to buffer Save to file
windows-ss 52ms 51ms
screenshot-desktop 152ms 141ms
desktop-screenshot n/a 63ms**

* Except for desktop-screenshot, it ran at 1706x960 as it's DPI unaware.

** Times are relative to lower resolution of 1706x960. If interpolated back to 1440p according to a DPI of 1.5, 63 * (1.5 ^ 2) = 141ms

I initially wanted to contribute it to this package, but edge-js only supplies binaries for even-numbered Node versions, requiring building of our own otherwise. :/

@Venryx
Copy link

Venryx commented Sep 5, 2021

Very nice library!

For most users, I would have to recommend yours -- both because of the better performance, and because it doesn't have a dependency on ffi-napi. (ffi-napi is nice, but it sometimes has build errors when upgrading to newer NodeJS versions, so it can be a pain for people not familiar with the process)

I was looking for a fast screenshotting library a while back, but couldn't find one. If I had seen yours, I probably wouldn't have even created the library above. 😜

That said, it's probably good I went ahead with it, as now there are two options available for people to choose from.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants