【问题标题】:Screenshot of active window outside borders边框外活动窗口的屏幕截图
【发布时间】:2014-12-17 09:21:28
【问题描述】:

我最近发现了一个代码来制作活动窗口的屏幕截图。它实际上可以工作,但是图像有点太大了,它有点超出当前窗口的边界。

这是我的程序截取的截图:

这是使用 alt+printscreen 截取的屏幕截图:

这是我的课:

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);
    }
}

我只希望它截取活动窗口而不是窗口外的一点点。我希望有人可以帮助我:)

【问题讨论】:

  • 我很好奇,CursorPosition的目的是什么?
  • 哦哇哦,其实没什么意义,我只是看到了哈哈。
  • 考虑窗口的边框尺寸:msdn.microsoft.com/en-us/library/…
  • @Aybe 这并没有给我我的活动窗口的大小,而且我怀疑这个类可以给我我的表单之外的活动窗口的任何属性。我用 IntPtr 找不到任何东西,我认为代码需要窗口的 IntPtr 才能从中获取详细信息。
  • 只是一个疯狂的建议,尝试关闭 Aero 主题并选择一个不涉及任何透明度或任何花哨混合的基本主题。

标签: c# screenshot


【解决方案1】:

我遇到了您描述的症状的问题。在我的情况下,这是由于窗口在系统中注册为“前景”的时刻与它实际完全显示在其他窗口前面的屏幕上的时刻之间的延迟。你可能观察到同样的情况。当您执行g.CopyFromScreen(...) 时,您会从屏幕区域中获取像素,该区域可能仍在从前一个前景窗口过渡到当前窗口。
在第一个保存的图像中,您可以看到我的图像捕获程序启动后 150 毫秒内的前景窗口(命令提示符)的屏幕截图:

如您所见,它是先前前景窗口像素 (Visual Studio) 和新像素的混合。

又花了 150 毫秒来完全更新屏幕:

所以,不是您的屏幕截图大小错误 - 而是新的前景窗口尚未“膨胀”到其最终边界。 一个简单(且丑陋)的解决方案是:在调用 g.CopyFromScreen(...) 之前插入 Thread.Sleep(...) 以给系统足够的时间来完全替换屏幕上的像素。

【讨论】:

    猜你喜欢
    • 2022-01-22
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多