我要将项目从.net迁移到.net-core,因为要求是在linux上运行应用程序。功能之一是窗口在主应用程序中运行的单独进程的屏幕捕获。
在.net-core之前,我使用两种方法从第二个窗口捕获图像。两种解决方案都使用IntPtr并从user32.dll或user32.dll导入函数来捕获图像(请参见代码段)。
// Solution A:
private System.Drawing.Bitmap PrintImageFromWindow(IntPtr hwnd)
{
// get windows rect
RECT rc = new RECT();
GetWindowRect(hwnd, ref rc);
// create compatybile bitmap from window
Bitmap bmp = new Bitmap(rc.Right - rc.Left, rc.Bottom - rc.Top, PixelFormat.Format32bppPArgb);
// create GDI+ graphic
Graphics gfxBmp = Graphics.FromImage(bmp);
IntPtr hdcBitmap = gfxBmp.GetHdc();
// copies a visual window into the specified device context
bool succeeded = PrintWindow(hwnd, hdcBitmap, 0);
gfxBmp.ReleaseHdc(hdcBitmap);
// bmp now contains the screenshot
if (!succeeded)
{
gfxBmp.FillRectangle(new SolidBrush(System.Drawing.Color.Gray), new Rectangle(System.Drawing.Point.Empty, bmp.Size));
}
IntPtr hRgn = CreateRectRgn(0, 0, 0, 0);
GetWindowRgn(hwnd, hRgn);
Region region = Region.FromHrgn(hRgn);
if (!region.IsEmpty(gfxBmp))
{
gfxBmp.ExcludeClip(region);
gfxBmp.Clear(System.Drawing.Color.Transparent);
}
// cleanup
gfxBmp.Dispose();
return bmp;
}
// SOLUTION B:
private System.Drawing.Bitmap ScreenshotImageFromWindow(IntPtr windowHandle)
{
// get context for window
IntPtr windowHDC = GetWindowDC(windowHandle);
if (windowHDC == IntPtr.Zero)
return null;
// Create a compatible DC which is used in a BitBlt from the window DC
IntPtr sourceDC = CreateCompatibleDC(windowHDC);
if (sourceDC == IntPtr.Zero)
{
return null;
}
// Create a compatible bitmap from the Window DC
System.Drawing.Rectangle rctForm = System.Drawing.Rectangle.Empty;
using (System.Drawing.Graphics grfx = System.Drawing.Graphics.FromHdc(windowHDC))
{
rctForm = System.Drawing.Rectangle.Round(grfx.VisibleClipBounds);
}
IntPtr sourceBMP = CreateCompatibleBitmap(windowHDC, rctForm.Width, rctForm.Height);
if (sourceBMP == IntPtr.Zero)// if no compatible bitmap
{
return null;
}
// Select the compatible bitmap into the compatible memory DC.
SelectObject(sourceDC, sourceBMP);
// Bit block transfer into our compatible memory DC.
if (!BitBlt(sourceDC, 0, 0, rctForm.Width, rctForm.Height, windowHDC, 0, 0, DWROP_SRCCOPY))
{
return null;
}
// Create GDI+ bitmap for window
System.Drawing.Bitmap bmp = System.Drawing.Image.FromHbitmap(sourceBMP);
// Clean up
DeleteObject(sourceBMP);
DeleteObject(sourceDC);
ReleaseDC(windowHandle, windowHDC);
// return bitmap image to user
return bmp; // return bitmap
}
// some of imported code
[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
[DllImport("gdi32.dll")]
private static extern IntPtr DeleteDC(IntPtr hDc);
[DllImport("user32.dll")]
private static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("gdi32.dll")]
private static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);
[DllImport("gdi32.dll")]
private static extern IntPtr DeleteObject(IntPtr hDc);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("user32.dll")]
private static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags);
是否会有其他解决方案来捕获窗口图像,这在Linux上也可以使用?还是可以在Linux上使用提到的导入功能?