制作窗口捕获支持透明度的位图



我具有一个函数,该功能捕获指定窗口句柄的图像,然后将图像保存到PNG文件中。我正在使用GDI32。

这可以正常工作,但是对于具有透明度的窗口(示例:典型的花式游戏启动器),透明区域将为绿色(或粉红色,取决于ternaryrasteroferations)。

这是执行捕获的功能:

private static Image CaptureWindow(IntPtr handle) {
    IntPtr hdc = GetWindowDC(handle);
    RECT winRect = new RECT();
    if (GetWindowRect(handle, out winRect)) {
        Size winSize = new Size(winRect.Right - winRect.Left, winRect.Bottom - winRect.Top);
        IntPtr hdcDest = CreateCompatibleDC(hdc);
        IntPtr hBitmap = CreateCompatibleBitmap(hdc, winSize.Width, winSize.Height);
        IntPtr hOld = SelectObject(hdcDest, hBitmap);
        //if (TransparentBlt(hdcDest, 0, 0, winSize.Width, winSize.Height, hdc, 0, 0, winSize.Width, winSize.Height, ColorToUint(Color.Green))) {
        if (BitBlt(hdcDest, 0, 0, winSize.Width, winSize.Height, hdc, 0, 0, TernaryRasterOperations.SRCCOPY)) {
            SelectObject(hdcDest, hOld);
            DeleteDC(hdcDest);
            ReleaseDC(handle, hdc);
            Image img = System.Drawing.Image.FromHbitmap(hBitmap);
            DeleteObject(hBitmap);
            return img;
        }
    }
    return null;
}

我尝试了bitblt和透明blt(msimg32)。

保存图像时,我尝试了:

img.Save("file.png", ImageFormat.Png);

img = img.Clone(new Rectangle(new Point(0, 0), img.Size), PixelFormat.Format32bppArgb);
img.Save("file.png", ImageFormat.Png);

img.MakeTransparent(Color.Green);
img.Save("file.png", ImageFormat.Png);

我还尝试使用某个地方建议的文件流来保存,但是所有这些方法都将相同的绿色应用于透明区域。

透明窗口不使用alpha通道,而是使用区域通知OS,顶级窗口的哪个区域被认为是窗口的一部分。区域在像素水平上是布尔值;换句话说,没有部分透明度。

我认为您需要使用GetWindowRgn获取区域数据。您可以尝试调用PtInRegion,以查看特定像素是否应该透明。如果那太慢,则可能有必要将整个区域绘制到屏幕外位图上,以便您可以捕获原始像素数据以更快地访问。

最新更新