screenshot-desktop
screenshot-desktop copied to clipboard
Windows Performance Improvements
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?
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.
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.
That'd be fantastic!
@G7495x I have a routine repeating every 2s. My task manager reports up to 3MB/S disk usage. Just reporting... https://github.com/bencevans/screenshot-desktop/issues/161#issue-589753434
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)
That sounds like a big improvement. Yes, very interested.
I looked around & noticed that https://github.com/bencevans/screenshot-desktop/pull/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
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
If anyone's still wondering, I've developed my research into a full package available from npm/github — windows-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. :/
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.