DarthAffe / ScreenCapture.NET

Fast and easy to use screen-capturing
GNU Lesser General Public License v2.1
68 stars 12 forks source link

Multiple screen #9

Closed jasonexe2000 closed 1 year ago

jasonexe2000 commented 1 year ago

When I use multiple screens to take screenshots, all of them except the first one show up as black screens.

IScreenCaptureService screenCaptureService = new DX11ScreenCaptureService();
IEnumerable<GraphicsCard> graphicsCards = screenCaptureService.GetGraphicsCards();
foreach (GraphicsCard graphicsCard in graphicsCards)
{
    IEnumerable<Display> displays = screenCaptureService.GetDisplays(graphicsCard);
    foreach (Display display in displays)
    {
        IScreenCapture screenCapture = screenCaptureService.GetScreenCapture(display);
        CaptureZone fullscreen = screenCapture.RegisterCaptureZone(0, 0, screenCapture.Display.Width, screenCapture.Display.Height);
        screenCapture.CaptureScreen();
        var image = Image.LoadPixelData<Bgra32>(fullscreen.Buffer, screenCapture.Display.Width, screenCapture.Display.Height);
        image.SaveAsJpeg("C:\\temp\\" + display.DeviceName + ".jpg");
    }
}
DarthAffe commented 1 year ago

That's an interesting issue. I've no idea why it behaves like this (and couldn't find anything in the docs about it) but it seems like the LastPresentTime for the first captured frame is always 0 if the capture was initialized after another call to AcquireNextFrame (even though they are not targeting the same display - I'd guess it's because they are on the same gpu but can't verify that).

There seem to be two ways to workaround that:

  1. Call CaptureScreen twice before saving the image (to have an actual update after first that returns without a frame) (EDIT: or to be more specific call it again until it returns true - which should always be second call in that case)
  2. Register all zones before starting to capture them