在C#中使用BitBlt捕获的屏幕截图在Windows 10上产生黑色图像

时间:2016-08-10 08:40:52

标签: c# screenshot bitblt windows-10-desktop

在c#中使用 BitBlt 捕获的屏幕截图在 Windows 10 上产生了黑色图像。请帮我解决这个问题。

屏幕截图是Chrome的黑色图像(启用硬件加速模式时)和IE / Edge窗口。

  

当硬件加速模式为ON时,输出图像仅适用于Windows 10和Chrome浏览器窗口中的Edge,IE浏览器窗口。除了所有其他窗口,包括透明窗口截图都很好。

以下是代码:

const int Srccopy = 0x00CC0020;
var windowRect = new Rect();

GetWindowRect(handle, ref windowRect);
int width = windowRect.right - windowRect.left;
int height = windowRect.bottom - windowRect.top;

// get te hDC of the target window
IntPtr hdcSrc = GetWindowDC(handle);

// create a device context we can copy to
IntPtr hdcDest = CreateCompatibleDC(hdcSrc);

// create a bitmap we can copy it to,
IntPtr hBitmap = CreateCompatibleBitmap(hdcSrc, width, height);
// select the bitmap object
IntPtr hOld = SelectObject(hdcDest, hBitmap);

// bitblt over
BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, Srccopy);
// restore selection
SelectObject(hdcDest, hOld);
// clean up
DeleteDC(hdcDest);
ReleaseDC(handle, hdcSrc);

Image img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
DeleteObject(hBitmap);

1 个答案:

答案 0 :(得分:-1)

硬件加速窗口是使用叠加模式渲染的,这意味着BitBlt仅获得表示“嘿,这是叠加!”的像素。当不渲染叠加层时,将导致黑色图像-如果正在渲染,则始终会看到 current 渲染,而不是时间冻结的东西。您不会捕获屏幕上显示的像素,而只是捕获窗口渲染方式的一些内部细节。

幸运的是,解决方案非常简单:

BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, 
       CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);

(您可以将BitBlt的P / Invoke定义修改为使用CopyPixelOperation而不是int,或将这些值强制转换为int。

请注意,请不要忘记检查返回值并相应地处理错误。