Files
2026-10-24 13:02:19 +08:00

67 lines
2.5 KiB
C#

using anjianjingling.Native;
namespace anjianjingling.Vision
{
/// <summary>
/// 屏幕/区域/窗口截图(GDI BitBlt)。
/// </summary>
public sealed class ScreenCapture
{
/// <summary>截取整个虚拟屏幕(所有显示器)。</summary>
public Bitmap CaptureScreen()
{
int x = Win32.GetSystemMetrics(Win32.SM_XVIRTUALSCREEN);
int y = Win32.GetSystemMetrics(Win32.SM_YVIRTUALSCREEN);
int w = Win32.GetSystemMetrics(Win32.SM_CXVIRTUALSCREEN);
int h = Win32.GetSystemMetrics(Win32.SM_CYVIRTUALSCREEN);
return CaptureRegion(x, y, w, h);
}
/// <summary>截取指定屏幕区域。</summary>
public Bitmap CaptureRegion(int x, int y, int width, int height)
{
if (width <= 0 || height <= 0)
throw new ArgumentException($"截图区域非法:({x},{y},{width},{height})");
var bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
using (var g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(x, y, 0, 0, new Size(width, height), CopyPixelOperation.SourceCopy);
}
return bmp;
}
/// <summary>
/// 截取指定窗口(含被遮挡部分,依赖 PrintWindow;部分程序不支持则返回 null)。
/// </summary>
public Bitmap? CaptureWindow(IntPtr hWnd)
{
if (!Win32.GetClientRect(hWnd, out var rc) || rc.Width <= 0 || rc.Height <= 0)
return null;
var bmp = new Bitmap(rc.Width, rc.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
using (var g = Graphics.FromImage(bmp))
{
IntPtr hdc = g.GetHdc();
bool ok = Win32.PrintWindow(hWnd, hdc, Win32.PW_RENDERFULLCONTENT);
g.ReleaseHdc(hdc);
if (!ok)
{
bmp.Dispose();
return null;
}
}
return bmp;
}
/// <summary>截图并保存到文件。</summary>
public string SaveRegion(int x, int y, int width, int height, string path)
{
using var bmp = CaptureRegion(x, y, width, height);
Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path))!);
bmp.Save(path, System.Drawing.Imaging.ImageFormat.Png);
return Path.GetFullPath(path);
}
}
}