-1

I would like to take screenshots at a defined interval of up to 20 ms. I don't think I can use the Timer class, as it's max resolution of ~ 15 ms could be a problem. However, my biggest problem is that taking a screenshot takes too long time:

Stopwatch myStopwatch = new Stopwatch();
myStopwatch.Start();

Bitmap printscreen = new Bitmap(1280, 720);
Graphics graphics = Graphics.FromImage(printscreen as Image);
graphics.CopyFromScreen(200, 200, 0, 0, new Size(1280, 720));
printscreen.Save(myOutputLocation + "image" + myImageCount.ToString() + ".png");
myImageCount += 1;

myStopwatch.Stop();
MessageBox.Show(myStopwatch.Elapsed.TotalMilliseconds.ToString());
// Elapsed time is anywhere between 60 - 95 ms

A high precision timer is able to deliver the precision I need, but I have read that your executed code should be faster than 1 millisecond. How can I speed up my code?

Xrio
  • 155
  • 2
  • 9
  • 7
    You want to write 50 files to a disk *every second*? Are you mad? – Phylogenesis Aug 11 '17 at 15:18
  • @Phylogenesis Oh, maybe it's not possible? – Xrio Aug 11 '17 at 15:19
  • Going by the fact your resolution is 1280x720, I am going to assume this is on a fairly cheap laptop. Your hard disk will almost certainly be a 5400rpm variety and there is absolutely no way it will be able to handle that sort of load. – Phylogenesis Aug 11 '17 at 15:22
  • @Phylogenesis My resolution is 1920x1080, I am only capturing a portion of the screen. I use a desktop computer, but it's performance is not the best. Using the Timer class and an interval of 100 ms, it was able to keep up, but with an interval < 40 ms, it did not keep up anymore. – Xrio Aug 11 '17 at 15:30
  • How long is the sequence you want to record and why you need 1000fps? Normal monitors can just handle 60-240fps which results in 16ms to 4ms per Frame. If you record faster it could result in a list of identical pictures or tearing inside the pictures. – Auskennfuchs Aug 11 '17 at 15:32
  • If you're intent on doing something like this, then you are going to need an SSD to support the I/O load (multiple disk seeks absolutely cripple mechanical hard drive performance). Even then, if you run this code for any sort of time you will run into issues with NTFS and its dislike of containing several thousand files in a single directory. – Phylogenesis Aug 11 '17 at 15:33
  • 1
    What's the reasoning behind this? If you need a screen recorder, there are a million different free existing products to do that. This may be an XY Problem. – gilliduck Aug 11 '17 at 15:37
  • @Auskennfuchs The sequence I would like to record can be anywhere from 1 minute to possibly 20 minutes. I don't need 1000 fps. I am aming for up to 50 fps, which results in an interval of 1000 ms / 50 fps = 20 ms. – Xrio Aug 11 '17 at 15:39
  • @gilliduck Yes, I would like to record the screen, but I want the output to be images rather than a video file. I could of course extract the images from a video file created by a screen recorder, but I would like to make my own program. I am open for suggestions on how to record the screen as an image sequence. – Xrio Aug 11 '17 at 15:44
  • As everyone has said, unless you're doing this for only a few seconds, you're going to overload the capabilities of your computer. Perhaps you want to record after every mouse click, or some specific event(s) that is trackable vs every few milliseconds. – gilliduck Aug 11 '17 at 15:46
  • What you need is a mirror driver. These operations are too resource intensive for higher level languages. Check this out: http://www.demoforge.com/dfmirage.htm – JuanR Aug 11 '17 at 15:47
  • 1
    FYI, based on your earlier comment of once every 20 ms for 1-20 minutes, you're looking at 60 thousand to 1.2 million images.... – gilliduck Aug 11 '17 at 15:48
  • @gilliduck I will end up with many images, but your numbers are too high I think. One image every 20 ms = 50 fps. 1 minute = 50 fps * 60 seconds = 3000 images. 20 minutes = 50 fps * 1200 seconds = 60000 images. – Xrio Aug 11 '17 at 16:35

1 Answers1

-1

You should not try to save the image in sequence, because IO-operations are really expensive even with a SSD. You could insert every image into a queue and start a thread which polls this queue and saves the images asynchronously. In C# you can use the ConcurrentQueue to be thread safe on insert and reading.

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
Auskennfuchs
  • 1,577
  • 9
  • 18
  • Please don't post links to non-english sites. I have changed your link to the English version (en-us instead of de-de) – Camilo Terevinto Aug 11 '17 at 15:23
  • You'll just end up with a queue of stuff waiting to be written to disk, you're just pushing the problem to another set of code. – DavidG Aug 11 '17 at 15:24
  • Do you know an alternative? He want's to capture more pictures than he is able with his implementation. He hasn't provided information if the images should be flawless or can be compressed. Second he can try to encode the data directly to a videoformat. But he needs a queue to fill the videoencoder, too. – Auskennfuchs Aug 11 '17 at 15:40
  • 1
    The key part of what you said there is *He hasn't provided information*, this means you can't really answer the question at all so you should be reluctant to post. Also, sometimes, something is just not possible and it seems that is the case here really. – DavidG Aug 11 '17 at 15:51
  • @Auskennfuchs I will take a look at your suggestion. I would like to choose between taking lossless or compressed images. Currently, I do this using the ImageFormat class. – Xrio Aug 11 '17 at 15:53