Захват виртуального экрана (все мониторы) - PullRequest
6 голосов
/ 31 марта 2011

Я пытаюсь получить скриншот всего виртуального экрана.Это означает изображение не только основного экрана, но и каждого экрана, подключенного к компьютеру.

Есть ли способ сделать это?Я пытался использовать это, но это не сработало:

Bitmap b = new Bitmap(SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height);
Graphics g = Graphics.FromImage(b);
this.Size = new Size(SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height);
g.CopyFromScreen(0, 0, 0, 0, b.Size);

Ответы [ 3 ]

6 голосов
/ 31 марта 2011

Документация гласит: Graphics.CopyFromScreen(Int32, Int32, Int32, Int32, Size): выполняет битовую передачу цветовых данных, соответствующих прямоугольнику пикселей, с экрана на поверхность рисования Графика. "Но виртуальный экран не обязательно является прямоугольником: представьте себе два монитора с разрешением 1920x1200 и 1280x1024. Поэтому вам нужно создать растровое изображение, как вы, затем перечислить свои мониторы и выполнить CopyFromScreen() для каждого из них.

Редактировать: Если, например, у вас есть два монитора, один с разрешением 1280x1024, стоящий на слева 1920x1200, тогда координаты первого будут (- 1280,0) - (0, 1024). Поэтому вам нужно выполнить memoryGraphics.CopyFromScreen(-1280, 0, 0, 0, s);, где s - это Size(1280,1024). Для второго вам нужно позвонить memoryGraphics.CopyFromScreen(0, 0, *1280*, 0, s);, а s будет Size(1920, 1200). Надеюсь, это поможет.

2 голосов
/ 23 июня 2011

Как сказали Игорь и Ганс, вы должны указать исходную координату:

Bitmap screenshot = new Bitmap(
    SystemInformation.VirtualScreen.Width, 
    SystemInformation.VirtualScreen.Height, 
    PixelFormat.Format32bppArgb);

Graphics screenGraph = Graphics.FromImage(screenshot);

screenGraph.CopyFromScreen(
    SystemInformation.VirtualScreen.X, 
    SystemInformation.VirtualScreen.Y, 
    0, 
    0, 
    SystemInformation.VirtualScreen.Size, 
    CopyPixelOperation.SourceCopy);
2 голосов
/ 31 марта 2011

Игорь прав, передача 0, 0 для аргументов SourceX / Y неверна.Выполните итерацию экземпляров Screen в свойстве Screen.AllScreens, чтобы найти ограничивающий прямоугольник.Помните, что в CopyFromScreen() есть ошибка, он не может захватывать многослойные окна (типа, в котором установлено TransparencyKey или Opacity).Проверьте мой ответ в этой теме , чтобы найти обходной путь.

Остерегайтесь того, что захват всего рабочего стола не всегда практичен, вы получите много черного цвета, если экраны расположены не идеальноПрямоугольник и исключение OutOfMemory не редкость на 32-разрядной машине с дисплеями высокого разрешения.

...