Сделайте скриншот окна, используя C # .NET - отсутствует информация о пикселях - PullRequest
1 голос
/ 26 июля 2010

Я пытаюсь сделать снимок экрана с помощью C # .NET, вызвав Windows API.Я придумал следующий код:

    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() метода.

Проблема в том, , когда я пытаюсь сделать снимок экрана развернутого окна под управлением Windows7, заголовок и граница (а иногда и другие части окна) являются черными .

Я думаю, что это вызвано либо тем, что окно является многослойным, либо тем, что строка заголовка окнауправляется самим окном, и поэтому информация о пикселях не может быть доступна (как я где-то читал).

У кого-нибудь есть идеи, как исправить это поведение?

1 Ответ

2 голосов
/ 26 июля 2010

Вы вызываете все виды 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);
}
...