All the methods I've found are somehow UI dependent. So, how to capture all displays without any dependency and third party?
You can use GetSystemMetrics function with SM_CXVIRTUALSCREEN
and SM_CYVIRTUALSCREEN
parameters for entire desktop. It will be handle all virtual displays.
using System;
using System.ComponentModel;//You can remove it if you will catch the below exception from another layer
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
namespace Helpers {
public static class HelperScreenShot {
public static void TakeAndSaveByAllScreen(ImageFormat imageFormat, string fullFileName = null) {
var img = CopyFromScreen();
if(img == null) return;
if(string.IsNullOrWhiteSpace(fullFileName)) {
fullFileName = $"{Guid.NewGuid()}.{imageFormat.ToString().ToLower()}";
}
img.Save(fullFileName, imageFormat);
}
public static byte[] TakeAsBinary(ImageFormat imageFormat) {
using var image = CopyFromScreen();
if(image == null) return default;
using var ms = new MemoryStream();
image.Save(ms, imageFormat);
return ms.ToArray();
}
private static Bitmap CopyFromScreen() {
try {
var size = HelperDisplay.GetVirtualScreenSize();
var image = new Bitmap(size.Width, size.Height);
using var graphics = Graphics.FromImage(image);
graphics.CopyFromScreen(Point.Empty, Point.Empty, size);
return image;
}
catch(Win32Exception) {//When screen saver is active
return null;
}
}
private static class HelperDisplay {
[DllImport("user32.dll")]
private static extern int GetSystemMetrics(MetricType metricType);
public static Size GetVirtualScreenSize() {
var width = GetSystemMetrics(MetricType.VirtualScreenWidth);
var height = GetSystemMetrics(MetricType.VirtualScreenHeight);
return new Size(width, height);
}
private enum MetricType {
VirtualScreenWidth = 78,
VirtualScreenHeight = 79
}
}
}
}
var dir = Path.Combine("images", "screenshot");
var imgFormat = ImageFormat.Png;
var fileName = $"{Guid.NewGuid()}.{imgFormat.ToString().ToLower()}";
fileName = Path.Combine(dir, fileName);
if(!Directory.Exists(dir)) {
Directory.CreateDirectory(dir);
}
HelperScreenShot.TakeAndSaveByAllScreen(fileName, imgFormat);
//or
var binaryImg = HelperScreenShot.TakeAsBinary(imgFormat);
Further Reading:
Multiple Monitor System Metrics
winuser.h header
How do you use System.Drawing in .NET Core?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.