有没有所有虚拟显示的截图方法?
Is there a method of screenshot for all virtual display?
我发现的所有方法都以某种方式 UI 依赖。那么,如何在没有任何依赖和第三方的情况下捕获所有显示?
您可以对整个桌面使用带有 SM_CXVIRTUALSCREEN
和 SM_CYVIRTUALSCREEN
参数的 GetSystemMetrics 函数。它将处理所有虚拟显示器。
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);
进一步阅读:
Multiple Monitor System Metrics
winuser.h header
How do you use System.Drawing in .NET Core?
我发现的所有方法都以某种方式 UI 依赖。那么,如何在没有任何依赖和第三方的情况下捕获所有显示?
您可以对整个桌面使用带有 SM_CXVIRTUALSCREEN
和 SM_CYVIRTUALSCREEN
参数的 GetSystemMetrics 函数。它将处理所有虚拟显示器。
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);
进一步阅读:
Multiple Monitor System Metrics
winuser.h header
How do you use System.Drawing in .NET Core?