4

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

1 回答 1

0

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

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

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

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

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

于 2019-09-05T07:48:12.240 回答