使用 C# .NET 截取窗口的屏幕截图 - 缺少像素信息

发布于 2024-09-11 02:09:09 字数 1398 浏览 0 评论 0原文

我正在尝试通过调用 Windows API 使用 C# .NET 截取窗口的屏幕截图。我想出了以下代码:

    public void ScreenshotWindow(IntPtr windowHandle) {
        Rect Rect = new Rect();

        GetWindowRect(windowHandle, out Rect);
        int width = Rect.right - Rect.left;
        int height = Rect.bottom - Rect.top;

        IntPtr windowDeviceContext = GetWindowDC(windowHandle);
        IntPtr destDeviceContext = CreateCompatibleDC(windowDeviceContext);
        IntPtr bitmapHandle = CreateCompatibleBitmap(windowDeviceContext, width, height);
        IntPtr oldObject = SelectObject(destDeviceContext, bitmapHandle);
        BitBlt(destDeviceContext, 0, 0, width, height, windowDeviceContext, 0, 0, CAPTUREBLT | SRCCOPY);
        SelectObject(destDeviceContext, oldObject);
        DeleteDC(destDeviceContext);
        ReleaseDC(windowHandle, destDeviceContext);

        Image screenshot = Image.FromHbitmap(bitmapHandle);
        DeleteObject(bitmapHandle);

        screenshot.Save("C:\\Screenshots\\" + windowHandle.ToString() + ".png", System.Drawing.Imaging.ImageFormat.Png);
    }

这是一系列常见的Windows API调用来获取窗口屏幕截图。

请注意,我并不是在寻找获取屏幕截图的替代方法。我想比较这种(固定)方法的速度和 .NET Graphics.CopyFromScreen() 方法的速度。

问题是,当我尝试对运行 Windows 7 的最大化窗口进行屏幕截图时,标题栏和边框(有时是窗口的其他部分)是黑色的

我认为这是由于窗口是分层的,或者因为窗口的标题栏是由窗口本身管理的,因此无法访问像素信息(正如我在某处读过的那样)。

有谁知道如何解决此行为?

I am attempting to take a screenshot of a window using C# .NET by calling Windows API. I came up with the following code:

    public void ScreenshotWindow(IntPtr windowHandle) {
        Rect Rect = new Rect();

        GetWindowRect(windowHandle, out Rect);
        int width = Rect.right - Rect.left;
        int height = Rect.bottom - Rect.top;

        IntPtr windowDeviceContext = GetWindowDC(windowHandle);
        IntPtr destDeviceContext = CreateCompatibleDC(windowDeviceContext);
        IntPtr bitmapHandle = CreateCompatibleBitmap(windowDeviceContext, width, height);
        IntPtr oldObject = SelectObject(destDeviceContext, bitmapHandle);
        BitBlt(destDeviceContext, 0, 0, width, height, windowDeviceContext, 0, 0, CAPTUREBLT | SRCCOPY);
        SelectObject(destDeviceContext, oldObject);
        DeleteDC(destDeviceContext);
        ReleaseDC(windowHandle, destDeviceContext);

        Image screenshot = Image.FromHbitmap(bitmapHandle);
        DeleteObject(bitmapHandle);

        screenshot.Save("C:\\Screenshots\\" + windowHandle.ToString() + ".png", System.Drawing.Imaging.ImageFormat.Png);
    }

It is a common series of Windows API calls to obtain window screenshot.

Note that I am not looking for alternative ways of obtaining screenshots. I would like to to compare speed of this (fixed) approach and the speed of .NET Graphics.CopyFromScreen() method.

The problem is, when I attempt to take a screenshot of a maximized window running Windows 7, the titlebar and the border (and sometimes other parts of the window) are black.

I think this is caused either by the fact the window is layered or because the title bar of the window is managed by the window itself and therefore the pixel information cannot be accessed (as I have read somewhere).

Does anyone have an idea how to fix this behaviour?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

听闻余生 2024-09-18 02:09:09

您正在调用各种您应该远离的 API,因为 .NET 框架可以轻松地实现屏幕截图。这比你想象的要简单得多:

var screen = Screen.PrimaryScreen;

using (var bitmap = new Bitmap(screen.Bounds.Width, screen.Bounds.Height))
using (var graphics = Graphics.FromImage(bitmap))
{
    graphics.CopyFromScreen(new Point(screen.Bounds.Left, screen.Bounds.Top), new Point(0, 0), screen.Bounds.Size);
    bitmap.Save("Test.png", ImageFormat.Png);
}

You're calling all kinds of APIs you should be staying a long distance away from, because taking a screenshot is comfortably covered in the .NET framework. It's much simpler than you might think:

var screen = Screen.PrimaryScreen;

using (var bitmap = new Bitmap(screen.Bounds.Width, screen.Bounds.Height))
using (var graphics = Graphics.FromImage(bitmap))
{
    graphics.CopyFromScreen(new Point(screen.Bounds.Left, screen.Bounds.Top), new Point(0, 0), screen.Bounds.Size);
    bitmap.Save("Test.png", ImageFormat.Png);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文