gpt4 book ai didi

windows - PrintWindow 位图不同于 PrintScreen Key 位图

转载 作者:可可西里 更新时间:2023-11-01 12:42:56 27 4
gpt4 key购买 nike

当使用 Print Screen+Alt 组合键手动捕获窗口时,我得到以下信息:

enter image description here

但如果我尝试使用 Windows API 以编程方式执行此操作,我明白了:

enter image description here

为什么会出现差异?我如何以编程方式获得第一个?

这是我的代码:

    [DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, int nFlags);

public Bitmap PrintWindow()
{
Bitmap bmp = new Bitmap(windowRect.Width, windowRect.Height, PixelFormat.Format32bppArgb);
Graphics gfxBmp = Graphics.FromImage(bmp);
IntPtr hdcBitmap = gfxBmp.GetHdc();

bool success = PrintWindow(windowHandle, hdcBitmap, 0);
gfxBmp.ReleaseHdc(hdcBitmap);

if (!success)
{
Console.WriteLine("Error copying image");
Console.WriteLine(getLastError());
}

gfxBmp.Dispose();

return bmp;
}

更新:用 BitBlt 做同样的事情。

这是 code from CodeProject仍然返回黑色蒙版图像:

public Image CaptureWindow(IntPtr handle)
{
// get te hDC of the target window
IntPtr hdcSrc = User32.GetWindowDC(handle);
// get the size
User32.RECT windowRect = new User32.RECT();
User32.GetWindowRect(handle,ref windowRect);
int width = windowRect.right - windowRect.left;
int height = windowRect.bottom - windowRect.top;
// create a device context we can copy to
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc,width,height);
// select the bitmap object
IntPtr hOld = GDI32.SelectObject(hdcDest,hBitmap);
// bitblt over
GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);
// restore selection
GDI32.SelectObject(hdcDest,hOld);
// clean up
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(handle,hdcSrc);
// get a .NET image object for it
Image img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
GDI32.DeleteObject(hBitmap);

img.Save("SampleImage.png");
return img;
}

我已经尝试了很多 CopyPixelOperation 的组合(在 131,000 个中大约有 15,000 个),但它仍然不起作用。

使用 Windows 8,AMD Radeon HD 6870。


更新 2

window 似乎是透明的,让 window 的蓝色渗了进来。当我将窗口颜色更改为黑色时(使用 Windows 个性化对话框),我得到的结果与第二个窗口大致相似。不过边界仍然缺失。

我还没有找到解决方案,但这是对问题的洞察。

最佳答案

PrintWindow 不起作用的原因是因为它取决于对WM_PRINT 的正确处理。应用程序的消息。很多应用程序对 WM_PRINT 都不稳定,并且没有正确实现或测试过它。因此,依赖它不是一个好主意,除非您只在已知和经过测试的应用程序上使用它。

如果你想抓取屏幕上显示的窗口,只需从桌面窗口句柄 ( GetDesktopWindow() ) 和包含该窗口的矩形进行 blt。

透明度是窗口抓取的一个问题。捕捉现代 Windows 操作系统的窗口是不可能的,因为没有图像文件类型支持像模糊底层图像这样的幻想。但是,可以将简单的透明度捕获到 PNG 文件中。

谨慎假设窗口在屏幕上看起来是最好的。根据下面的内容,这可能不是真的。复制下面的任何内容也可能是个坏主意,因为它可能不会被批准出现在图像中,例如在 Excel 屏幕截图下出现在业务演示文稿中的明确背景图像:)。

如果您从桌面进行 blt,则会复制您在屏幕上看到的内容,包括任何覆盖窗口和底层窗口(透明的)。仅抓取窗口通常被认为“更干净”,就像使用 PrintWindow 一样,但您可能希望将其合成在您选择的背景上,如白色或蓝色。如果你想从屏幕上 blt,有一些方法可以暂时隐藏覆盖你的目标的窗口,但它是 EnumWindows 等的一大堆工作。

正确抓取窗口在 Windows 中不是一件容易的事,并且有许多屏幕抓取应用程序凭借它们处理这个问题的能力相互竞争。此外,在 Windows 中,有多种方法可以使窗口区域透明,并且它们也可以一起使用。

此外,在 Vista+ 中,还有 DWM thumbnail API这允许您获取在您的窗口上绘制的应用程序窗口的副本。有关演示和源代码,请参阅 ShareX (以前称为 zScreen)。

最后,你可以查看Open Broadcaster Software的来源,它使用 Direct3D 进行一些屏幕抓取。

关于windows - PrintWindow 位图不同于 PrintScreen Key 位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16351012/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com