我有一个功能,它捕获指定窗口句柄的图像,然后将图像保存到png文件。我正在使用gdi32。
这样可以正常工作,但对于具有透明度的窗口(例如:典型的花式游戏启动器),透明区域将为绿色(或粉红色,具体取决于TernaryRasterOperations)。
这是捕获的功能:
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和TransparentBlt(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通道,而是使用Regions通知操作系统顶级窗口的哪些区域被视为窗口的一部分。区域在像素级别是布尔值;换句话说,没有部分透明度。
我想你需要使用GetWindowRgn
来获取区域数据。从那里你可以尝试调用PtInRegion
来查看特定像素是否应该是透明的。如果这太慢,则可能需要将整个区域绘制到屏幕外位图,以便您可以抓取原始像素数据以便更快地访问。