在Windows Vista,Windows 7中截取屏幕截图,其中包含应用区域外的透明区域

Ste*_*don 14 c# gdi+ gdi windows-vista windows-7

我试图截取一个应用程序的屏幕截图,我想使不属于应用程序区域的矩形部分透明.因此,例如在标准的Windows应用程序上,我想使圆角透明.

我写了一个快速测试应用程序,适用于XP(或关闭aero的vista/windows 7):

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        Graphics g = e.Graphics;           

        // Just find a window to test with
        IntPtr hwnd = FindWindowByCaption(IntPtr.Zero, "Calculator");

        WINDOWINFO info = new WINDOWINFO();
        info.cbSize = (uint)Marshal.SizeOf(info);
        GetWindowInfo(hwnd, ref info);


        Rectangle r = Rectangle.FromLTRB(info.rcWindow.Left, info.rcWindow.Top, info.rcWindow.Right, info.rcWindow.Bottom);
        IntPtr hrgn = CreateRectRgn(info.rcWindow.Left, info.rcWindow.Top, info.rcWindow.Right, info.rcWindow.Bottom);
        GetWindowRgn(hwnd, hrgn);

        // fill a rectangle which would be where I would probably 
        // write some mask color
        g.FillRectangle(Brushes.Red, r);

        // fill the region over the top, all I am trying to do here 
        // is show the contrast between the applications region and 
        // the rectangle that the region would be placed in
        Region region = Region.FromHrgn(hrgn);
        region.Translate(info.rcWindow.Left, info.rcWindow.Top);
        g.FillRegion(Brushes.Blue, region);
    }
Run Code Online (Sandbox Code Playgroud)

当我在XP(或带有Aero的Vista/Windows 7)上运行这个测试应用程序时,我得到类似这样的东西,这很好,因为我可以找到一个可以在以后用于BitBlt的xor掩码.

删除死了Imageshack链接 - 截图

这是问题,在启用了Aero的Vista或Windows 7上,窗口上不一定有区域,实际上在大多数情况下没有.任何人都可以帮我找出在这些平台上构建这样的面具的方法吗?

以下是我已经尝试过的一些方法......

1.使用PrintWindow功能:这不起作用,因为它返回了关闭Aero的窗口截图,此窗口与Aero返回的窗口形状不同

2使用桌面窗口管理器API获取完整大小的缩略图:这不起作用,因为它直接绘制到屏幕上,而且我可以告诉您无法直接从此API获取屏幕截图.是的,我可以打开一个粉红色背景的窗口,显示缩略图,截取屏幕截图然后隐藏这个临时窗口,但这是一个糟糕的用户体验和一个完整的黑客,我宁愿没有我的名字.

3.使用Graphics.CopyFromScreen或其他一些pinvoke变体:这不起作用,因为我不能假设我需要信息的窗口位于屏幕上z顺序的顶部.

现在,我能想到的最好的解决方案是Windows 7和Vista上的特殊情况Aero通过硬编码我绘制的一些图形路径手动擦除角落但是这个解决方案很糟糕,因为任何执行自定义皮肤的应用程序都会破坏这个.

你能想到另一个或更好的解决方案吗?

如果您在这里,感谢您花时间阅读本文,感谢您提供的任何帮助或指导!

mdm*_*dma 8

如果您正在寻找已完成的应用程序,则会有7个捕获,它还会捕获半透明效果,因此可以将图像保存为PNG格式以供以后合成.

编辑:

原始问题和注释表明您希望在Windows Vista/7上生成一个区域,然后您可以使用该区域屏蔽捕获图像的部分,就像使用Windows XP和非Aero UI一样.使用区域不会为您提供所需的结果,因为窗口轮廓不是作为区域计算的,而是作为具有可变透明度的图像 - RGBA.该图像中的Alpha通道是您的遮罩,但它不是像区域一样的开关遮罩,而是一个渐变遮罩,其中包含从像素完全包含到完全遮盖的一系列值.

虽然它使用了未记录的API,但http://spazzarama.wordpress.com/2009/02/12/screen-capture-with-vista-dwm/上的代码将捕获到RGBA缓冲区,然后您可以使用它来渲染或保存阴影和其他半透明效果的图像完好无损.

DwmCapture.cs改变

BackBufferFormat = Format.X8R8G8B8
Run Code Online (Sandbox Code Playgroud)

BackBufferFormat = Format.A8R8G8B8
Run Code Online (Sandbox Code Playgroud)

(x8的> A8)

然后,您应该能够从捕获的缓冲区访问常用的RGB数据和透明度.然后可以将其保存为PNG或其他具有alpha通道的格式进行合成.