C# 在Windows Vista、Windows 7中拍摄屏幕截图,应用程序区域外有透明区域
我正在尝试拍摄一个应用程序的屏幕截图,我希望矩形中不属于应用程序区域的部分是透明的。例如,在标准windows应用程序上,我希望使圆角透明 我编写了一个快速的测试应用程序,可以在XP(或关闭aero的vista/Windows7)上运行: 当我在XP(或关闭Aero的Vista/Windows7)上运行这个测试应用程序时,我得到了类似的结果,这非常好,因为我可以从中找到一个xor掩码,以后可以与BitBlt一起使用 已删除死掉的Imageshack链接-屏幕截图 问题是,在Vista或启用Aero的Windows7上,窗口上不一定有区域,事实上在大多数情况下没有。有人能帮我想办法在这些平台上制作这样的面具吗 以下是我已经尝试过的一些方法 1。使用函数:这不起作用,因为它会返回Aero关闭时窗口的截图,并且此窗口与Aero打开时返回的窗口的形状不同 2使用获取完整大小的缩略图:这不起作用,因为它直接绘制到屏幕上,并且从我可以告诉您的情况来看,您无法直接从该api获取屏幕截图。是的,我可以打开一个粉红色背景的窗口,显示缩略图,截图,然后隐藏这个临时窗口,但这是一个可怕的用户体验和一个完整的黑客我宁愿没有我的名字 3。使用pinvoke或其他pinvoke变体:这不起作用,因为我不能假设我需要的信息窗口位于屏幕z顺序的顶部 现在,我能想到的最好的解决方案是在Windows7和Vista上使用特例Aero,通过对我绘制的一些图形路径进行硬编码来手动擦角,但这种解决方案会很糟糕,因为任何执行自定义蒙皮的应用程序都会打破这一点 你能想出另一个或更好的解决方案吗 如果你在这里,感谢你花时间阅读这篇文章,我感谢你能提供的任何帮助或指导 删除了一个可怕的想法,但在90年代会非常棒 您说使用DWMAPI只允许您直接捕获到屏幕上。。。你能创建一个屏幕外的窗口(比如说,X=-100000px,Y=-100000px)但可见(甚至可能隐藏?)并绘制屏幕截图吗?因为使用DWM时,每个窗口都有一个背景纹理,所以我认为即使目标不是直接出现在屏幕上,也可能会绘制得很好 另外,如果您想使用DirectX路线并访问窗口背后的实际DX纹理,我发现了一些可能有用的线索(尤其是第一个链接):C# 在Windows Vista、Windows 7中拍摄屏幕截图,应用程序区域外有透明区域,c#,windows-7,gdi+,gdi,windows-vista,C#,Windows 7,Gdi+,Gdi,Windows Vista,我正在尝试拍摄一个应用程序的屏幕截图,我希望矩形中不属于应用程序区域的部分是透明的。例如,在标准windows应用程序上,我希望使圆角透明 我编写了一个快速的测试应用程序,可以在XP(或关闭aero的vista/Windows7)上运行: 当我在XP(或关闭Aero的Vista/Windows7)上运行这个测试应用程序时,我得到了类似的结果,这非常好,因为我可以从中找到一个xor掩码,以后可以与BitBlt一起使用 已删除死掉的Imageshack链接-屏幕截图 问题是,在Vista或启用Aer
DwmCapture.cs
中更改
BackBufferFormat = Format.X8R8G8B8
到
(X8->A8)
然后,您应该能够从捕获的缓冲区访问通常的RGB数据和透明度。然后可以将其保存为PNG或其他格式,并使用alpha通道进行合成
如果您知道需要从哪个窗口获取信息,可以将其置于最前面,调用Graphics.CopyFromScreen,然后重置其z索引吗?我从经验中知道,Aero在项目处于背景时会做一些奇怪的事情,以使其玻璃界面正常工作(部分渲染等)。这可能不太好;但是,这是一种特殊情况,仅在启用Aero时使用。您可以查看的源代码,如主页上所述,它可以捕获圆角,并具有Aero Glass透明效果,并将其保存到PNG文件中。它是用C#编写的。有趣且经过深思熟虑的问题,我希望它得到更多的关注。您正在使用
GetWindowRgn()
获取窗口的区域。如果改用GetWindowDC()
(获取窗口的DC,包括标题栏),然后使用SelectObject()
或GetObject()
以这种方式检索区域,会发生什么情况?有什么不同吗?还有一个GetClipRgn()
,它可能会返回不同的形状。我还没有尝试过这种方法,我将在本周末尝试一下。尝试过,但不幸的是,它不起作用。如上所述,当打开Aero时,窗口的形状不同。嘿,我查看了示例,不幸的是,这种方法有两个问题。。。1.不支持用于获取Direct3D曲面的API,因此我无法使用这些函数和2。(回到1),它们似乎在Windows7和Vista之间发生了变化。所以显示的样本实际上不起作用
BackBufferFormat = Format.X8R8G8B8
BackBufferFormat = Format.A8R8G8B8