1

I wish to get a snapshot of the screen in the most efficient manner. This will be used in a program that runs in the background when other computationally intense programs (games) are running, and I do not want to impact on their performance (too much). The screenshot would occur multiple (10+) times a second so I want it to be as fast as possible.

Ideally I am looking for Delphi code, but am open to whatever will be best for this. I found the first function of this which works well, can anyone confirm/debunk that this is the fastest method to do this?

In addition, certain applications grab the entire screen (eg skyrim) and I think they bypass the Window system used in the above. The above link cannot get those images. Does anyone have an idea as to how to grab them?

rspencer
  • 2,651
  • 2
  • 21
  • 29
  • 1
    Try to grab screens using DIB http://msdn.microsoft.com/en-us/library/windows/desktop/dd183562%28v=vs.85%29.aspx. – Alexandr Aug 23 '13 at 11:49
  • 3
    Take a look at [Fastest method of screen capturing](http://stackoverflow.com/q/5069104/859646). Also I guess GDI approaches will not capture DirectX overlays. – JRL Aug 23 '13 at 12:23
  • 1
    DirectX games and videos will appear as black rectangle. Do a sanity check by pressing the PrintScr key and pasting into a bitmap editor, while running various targeted apps (games, videos, etc..) If you get black rectangles where the display should be, this is the DirectX problem. – Chris Thornton Aug 23 '13 at 13:20

1 Answers1

2

I suppose you mean Windows app only ? But even for windows, there is no way to do it so efficient as you asked. On many computers you will not be able to get 10+ FPS even if your app is the only running app. Probably most efficient way is to use mirroring driver, in this case you always will have copy of the screen, but driver will affect performance too, especially in such heavy applications like 3D games. (i even do not ask what you going to do with 10+ screens at the second, because whatever you do with them, it will take either CPU or HDD time and will slow down 3D apps too).

Yoo can capture not only whole screen of course, you can capture any part. You can use bitblt like this example shows:

procedure CaptureFromScreen(Dest: TBitmap; x, y, w, h, screenx, screeny: integer);
var
  DC: hWnd;
begin
  DC := GetDC(0);
  if DC = 0 then
    exit;
  bitblt(dest.canvas.handle, x, y, w, h, DC, screenx, screeny, SRCCOPY);
  ReleaseDC(0, DC);
end;

Sometimes it is usefull to use (CAPTUREBLT or SRCCOPY) instead of SRCCOPY. It helps to capture transparent items, but has some side effects, for example cursor may blink. And not sure how to capture picture from overlay. If you are watching movie, most probably player will use overlay and BITBLT return region filled with one color instead of picture.

Andrei Galatyn
  • 3,322
  • 2
  • 24
  • 38
  • Yeah, so it is Windows only. This is the first step of a back lighting system that changes the color of lights behind the screen (to reflect off a wall or whatever) according to what is displayed. – rspencer Aug 23 '13 at 12:26
  • Mirror drivers disable Aero effects in Windows Vista and 7, and are not supported in Windows 8: http://msdn.microsoft.com/en-us/library/windows/hardware/ff568315(v=vs.85).aspx – JRL Aug 23 '13 at 12:29
  • @rspencer For such task i think it would be better to capture frame only (4 relatively small bitmaps). Then you will be able to capture and process it with much higher FPS and reasonable CPU load. And result will be even better, light behind should "extend" desktop, so wall left from the screen should have kind of average color from left part of the screen only, ... – Andrei Galatyn Aug 23 '13 at 12:33
  • @AndreiGalatyn: Ah, yes that would be optimal. I wasn't sure if that would be possible though. It seems more likely that a whole screen capture would be accessible than small parts. However, if such a localized grab exists, that would be great! – rspencer Aug 23 '13 at 12:36