Capture screen of Window by handle

匿名 (未验证) 提交于 2019-12-03 02:03:01

问题:

I'm trying to capture only a specific Window in the desktop but I'm getting a mixed image, part of window and part desktop area.

What am I missing?

Here's my code:

RECT rect = new RECT();  if (!SetForegroundWindow(handle))     throw new Win32Exception(Marshal.GetLastWin32Error());  if (!GetWindowRect(handle, out rect))     throw new Win32Exception(Marshal.GetLastWin32Error());  Thread.Sleep(500);  Rectangle windowSize = rect.ToRectangle(); Bitmap target = new Bitmap(windowSize.Width, windowSize.Height); using (Graphics g = Graphics.FromImage(target)) {     g.CopyFromScreen(0, 0, 0, 0, new Size(windowSize.Width, windowSize.Height)); }  target.Save("foo.png", System.Drawing.Imaging.ImageFormat.Png); 

回答1:

I think the problem in your code is this line:

g.CopyFromScreen(0, 0, 0, 0, new Size(windowSize.Width, windowSize.Height)); 

It should be:

g.CopyFromScreen(windowSize.X, windowSize.Y, 0, 0, new Size(windowSize.Width, windowSize.Height)); 

Here is the method I personally use to get an image of a particular window - it might come in handy:

public Bitmap GetScreenshot() {     IntPtr hwnd = ihandle;//handle here      RECT rc;     Win32.GetWindowRect(new HandleRef(null, hwnd), out rc);      Bitmap bmp = new Bitmap(rc.Right - rc.Left, rc.Bottom - rc.Top, PixelFormat.Format32bppArgb);     Graphics gfxBmp = Graphics.FromImage(bmp);     IntPtr hdcBitmap;     try     {         hdcBitmap = gfxBmp.GetHdc();     }     catch     {         return null;     }     bool succeeded = Win32.PrintWindow(hwnd, hdcBitmap, 0);     gfxBmp.ReleaseHdc(hdcBitmap);     if (!succeeded)     {         gfxBmp.FillRectangle(new SolidBrush(Color.Gray), new Rectangle(Point.Empty, bmp.Size));     }     IntPtr hRgn = Win32.CreateRectRgn(0, 0, 0, 0);     Win32.GetWindowRgn(hwnd, hRgn);     Region region = Region.FromHrgn(hRgn);//err here once     if (!region.IsEmpty(gfxBmp))     {         gfxBmp.ExcludeClip(region);         gfxBmp.Clear(Color.Transparent);     }     gfxBmp.Dispose();     return bmp;  } 


回答2:

I'm improving on PixelZerg's answer, which doesn't include necessary using and external references...

To use the code below, simply create a ScreenCapture class instance and pass the handle of your C# Winforms-generated window to the GetScreenshot routine. This returns a bitmap object. To write that to a JPG file, pass the bitmap object to the WriteBitmapToFile method:

Add a using statement that references your ScreenCapture class:

using StackOverflow.Example.Utility; 

Now instantiate ScreenCapture and use it as shown:

var sc = new ScreenCapture(); var bitmap = sc.GetScreenshot(parentContainer.Handle); sc.WriteBitmapToFile("temp.jpg", bitmap); 

Here is the complete, compilable code for the ScreenCapture class:

using System; using System.Runtime.InteropServices; using System.Drawing; using System.Drawing.Imaging;  namespace StackOverflow.Example.Utility {      public class ScreenCapture     {         [DllImport("user32.dll")]         static extern int GetWindowRgn(IntPtr hWnd, IntPtr hRgn);          //Region Flags - The return value specifies the type of the region that the function obtains. It can be one of the following values.         const int ERROR = 0;         const int NULLREGION = 1;         const int SIMPLEREGION = 2;         const int COMPLEXREGION = 3;          [DllImport("user32.dll")]         [return: MarshalAs(UnmanagedType.Bool)]         static extern bool GetWindowRect(HandleRef hWnd, out RECT lpRect);          [DllImport("gdi32.dll")]         static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);          [DllImport("user32.dll", SetLastError = true)]         [return: MarshalAs(UnmanagedType.Bool)]         static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);          [StructLayout(LayoutKind.Sequential)]         public struct RECT         {             public int Left, Top, Right, Bottom;              public RECT(int left, int top, int right, int bottom)             {                 Left = left;                 Top = top;                 Right = right;                 Bottom = bottom;             }              public RECT(System.Drawing.Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom) { }              public int X             {                 get { return Left; }                 set { Right -= (Left - value); Left = value; }             }              public int Y             {                 get { return Top; }                 set { Bottom -= (Top - value); Top = value; }             }              public int Height             {                 get { return Bottom - Top; }                 set { Bottom = value + Top; }             }              public int Width             {                 get { return Right - Left; }                 set { Right = value + Left; }             }              public System.Drawing.Point Location             {                 get { return new System.Drawing.Point(Left, Top); }                 set { X = value.X; Y = value.Y; }             }              public System.Drawing.Size Size             {                 get { return new System.Drawing.Size(Width, Height); }                 set { Width = value.Width; Height = value.Height; }             }              public static implicit operator System.Drawing.Rectangle(RECT r)             {                 return new System.Drawing.Rectangle(r.Left, r.Top, r.Width, r.Height);             }              public static implicit operator RECT(System.Drawing.Rectangle r)             {                 return new RECT(r);             }              public static bool operator ==(RECT r1, RECT r2)             {                 return r1.Equals(r2);             }              public static bool operator !=(RECT r1, RECT r2)             {                 return !r1.Equals(r2);             }              public bool Equals(RECT r)             {                 return r.Left == Left && r.Top == Top && r.Right == Right && r.Bottom == Bottom;             }              public override bool Equals(object obj)             {                 if (obj is RECT)                     return Equals((RECT)obj);                 else if (obj is System.Drawing.Rectangle)                     return Equals(new RECT((System.Drawing.Rectangle)obj));                 return false;             }              public override int GetHashCode()             {                 return ((System.Drawing.Rectangle)this).GetHashCode();             }              public override string ToString()             {                 return string.Format(System.Globalization.CultureInfo.CurrentCulture, "{{Left={0},Top={1},Right={2},Bottom={3}}}", Left, Top, Right, Bottom);             }         }         public Bitmap GetScreenshot(IntPtr ihandle)         {             IntPtr hwnd = ihandle;//handle here              RECT rc;             GetWindowRect(new HandleRef(null, hwnd), out rc);              Bitmap bmp = new Bitmap(rc.Right - rc.Left, rc.Bottom - rc.Top, PixelFormat.Format32bppArgb);             Graphics gfxBmp = Graphics.FromImage(bmp);             IntPtr hdcBitmap;             try             {                 hdcBitmap = gfxBmp.GetHdc();             }             catch             {                 return null;             }             bool succeeded = PrintWindow(hwnd, hdcBitmap, 0);             gfxBmp.ReleaseHdc(hdcBitmap);             if (!succeeded)             {                 gfxBmp.FillRectangle(new SolidBrush(Color.Gray), new Rectangle(Point.Empty, bmp.Size));             }             IntPtr hRgn = CreateRectRgn(0, 0, 0, 0);             GetWindowRgn(hwnd, hRgn);             Region region = Region.FromHrgn(hRgn);//err here once             if (!region.IsEmpty(gfxBmp))             {                 gfxBmp.ExcludeClip(region);                 gfxBmp.Clear(Color.Transparent);             }             gfxBmp.Dispose();             return bmp;         }          public void WriteBitmapToFile(string filename, Bitmap bitmap)         {             bitmap.Save(filename, ImageFormat.Jpeg);         }     } } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!