在c#中使用BitBlt捕获的截图在Windows 10上显示为黑色图像

本文关键字:Windows 显示 图像 黑色 BitBlt | 更新日期: 2023-09-27 18:01:44

在c#中使用BitBlt捕获的截图导致Windows 10上出现黑色图像。请帮我解决这个问题。

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

当硬件加速模式开启时,只有Edge、windows 10中的IE浏览器窗口和Chrome浏览器窗口输出图像为黑色。除了所有其他窗口,包括透明窗口的截图都很好。

代码如下:

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

在c#中使用BitBlt捕获的截图在Windows 10上显示为黑色图像

硬件加速窗口是使用覆盖模式渲染的,这意味着你的BitBlt只能得到说"嘿,这是覆盖!"的像素。当覆盖层没有被渲染时,这将导致一个黑色的图像-如果它被渲染,你总是看到当前渲染,而不是时间冻结的东西。你不是在捕捉屏幕上显示的像素,只是一些窗口渲染如何工作的内部细节。

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

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

(你可以修改你的BitBlt p/Invoke定义来使用CopyPixelOperation而不是int,或者只是自己将这些值转换为int)。

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

相关文章: