我最近找到了一个代码来制作活动窗口的屏幕截图。它实际上工作但是图像有点太大,它在当前窗口的边界之外稍微有点。
这是我的班级:
public static class Screenshotter
{
[DllImport("user32.dll")]
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
private static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left; // x position of upper-left corner
public int Top; // y position of upper-left corner
public int Right; // x position of lower-right corner
public int Bottom; // y position of lower-right corner
}
public static void MakeScreenshot()
{
var foregroundWindowsHandle = GetForegroundWindow();
var rect = new RECT();
GetWindowRect(foregroundWindowsHandle, out rect);
Rectangle bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
Bitmap bmp = new Bitmap(bounds.Width, bounds.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size);
}
bmp.Save("test.png", ImageFormat.Png);
}
}
我只想让它截图显示活动窗口而不是窗外的一点点。我希望有人可以帮助我:)。
答案 0 :(得分:0)
我遇到了你所描述症状的问题。在我的情况下,这是因为窗口在系统中注册为“前景”的时刻和实际完全显示在其他窗口前面的屏幕上的时刻之间的延迟。你可能会观察到同样的情况当您执行g.CopyFromScreen(...)
时,您将获得屏幕区域中可能仍处于从前一个前景窗口转换到当前窗口的像素。
在第一个保存的图像中,您可以看到在我的图像捕获程序启动后150毫秒内制作的前景窗口(命令提示符)的屏幕截图:
如您所见,它是先前前景窗口像素(Visual Studio)和新像素的混合。
完全更新屏幕需要150毫秒:
因此,屏幕截图的大小并不正确 - 这是新的前景窗口尚未“膨胀”到最终边界。
一个简单(丑陋)的解决方案是:在调用Thread.Sleep(...)
之前插入g.CopyFromScreen(...)
,为系统提供足够的时间来完全替换屏幕上的像素。