捕获活动窗口的截图?

我正在制作一个屏幕捕捉应用程序,一切都很好。 我需要做的就是捕获活动窗口并截取这个活动窗口。 有谁知道我怎么能做到这一点?

ScreenCapture sc = new ScreenCapture(); // capture entire screen, and save it to a file Image img = sc.CaptureScreen(); // display image in a Picture control named imageDisplay this.imageDisplay.Image = img; // capture this window, and save it sc.CaptureWindowToFile(this.Handle,"C:\\temp2.gif",ImageFormat.Gif); 

http://www.developerfusion.com/code/4630/capture-a-screen-shot/

 Rectangle bounds = Screen.GetBounds(Point.Empty); using(Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height)) { using(Graphics g = Graphics.FromImage(bitmap)) { g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size); } bitmap.Save("test.jpg", ImageFormat.Jpeg); } 

用于捕获当前的窗口使用

  Rectangle bounds = this.Bounds; using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height)) { using (Graphics g = Graphics.FromImage(bitmap)) { g.CopyFromScreen(new Point(bounds.Left,bounds.Top), Point.Empty, bounds.Size); } bitmap.Save("C://test.jpg", ImageFormat.Jpeg); } 

我build议下一个解决scheme,分别捕获任何当前活动窗口(不仅仅是我们的C#应用​​程序)或整个屏幕,相对于窗口或屏幕左上angular的光标位置确定:

 public enum enmScreenCaptureMode { Screen, Window } class ScreenCapturer { [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] private static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect); [StructLayout(LayoutKind.Sequential)] private struct Rect { public int Left; public int Top; public int Right; public int Bottom; } public Bitmap Capture(enmScreenCaptureMode screenCaptureMode = enmScreenCaptureMode.Window) { Rectangle bounds; if (screenCaptureMode == enmScreenCaptureMode.Screen) { bounds = Screen.GetBounds(Point.Empty); CursorPosition = Cursor.Position; } else { var foregroundWindowsHandle = GetForegroundWindow(); var rect = new Rect(); GetWindowRect(foregroundWindowsHandle, ref rect); bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top); CursorPosition = new Point(Cursor.Position.X - rect.Left, Cursor.Position.Y - rect.Top); } var result = new Bitmap(bounds.Width, bounds.Height); using (var g = Graphics.FromImage(result)) { g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size); } return result; } public Point CursorPosition { get; protected set; } } 

KvanTTT的代码工作得很好。 我扩展了一下,以便在保存格式上有更多的灵活性,以及​​通过hWnd,.NET Control / Form保存的function。 你可以得到一个位图或保存到文件,有几个选项。

 using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Runtime.InteropServices; using System.Windows.Forms; namespace MosaiqPerformanceMonitor { public enum CaptureMode { Screen, Window } public static class ScreenCapturer { [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] private static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect); [StructLayout(LayoutKind.Sequential)] private struct Rect { public int Left; public int Top; public int Right; public int Bottom; } [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern IntPtr GetDesktopWindow(); /// <summary> Capture Active Window, Desktop, Window or Control by hWnd or .NET Contro/Form and save it to a specified file. </summary> /// <param name="filename">Filename. /// <para>* If extension is omitted, it's calculated from the type of file</para> /// <para>* If path is omitted, defaults to %TEMP%</para> /// <para>* Use %NOW% to put a timestamp in the filename</para></param> /// <param name="mode">Optional. The default value is CaptureMode.Window.</param> /// <param name="format">Optional file save mode. Default is PNG</param> public static void CaptureAndSave(string filename, CaptureMode mode = CaptureMode.Window, ImageFormat format = null) { ImageSave(filename, format, Capture(mode)); } /// <summary> Capture a specific window (or control) and save it to a specified file. </summary> /// <param name="filename">Filename. /// <para>* If extension is omitted, it's calculated from the type of file</para> /// <para>* If path is omitted, defaults to %TEMP%</para> /// <para>* Use %NOW% to put a timestamp in the filename</para></param> /// <param name="handle">hWnd (handle) of the window to capture</param> /// <param name="format">Optional file save mode. Default is PNG</param> public static void CaptureAndSave(string filename, IntPtr handle, ImageFormat format = null) { ImageSave(filename, format, Capture(handle)); } /// <summary> Capture a specific window (or control) and save it to a specified file. </summary> /// <param name="filename">Filename. /// <para>* If extension is omitted, it's calculated from the type of file</para> /// <para>* If path is omitted, defaults to %TEMP%</para> /// <para>* Use %NOW% to put a timestamp in the filename</para></param> /// <param name="c">Object to capture</param> /// <param name="format">Optional file save mode. Default is PNG</param> public static void CaptureAndSave(string filename, Control c, ImageFormat format = null) { ImageSave(filename, format, Capture(c)); } /// <summary> Capture the active window (default) or the desktop and return it as a bitmap </summary> /// <param name="mode">Optional. The default value is CaptureMode.Window.</param> public static Bitmap Capture(CaptureMode mode = CaptureMode.Window) { return Capture(mode == CaptureMode.Screen ? GetDesktopWindow() : GetForegroundWindow()); } /// <summary> Capture a .NET Control, Form, UserControl, etc. </summary> /// <param name="c">Object to capture</param> /// <returns> Bitmap of control's area </returns> public static Bitmap Capture(Control c) { return Capture(c.Handle); } /// <summary> Capture a specific window and return it as a bitmap </summary> /// <param name="handle">hWnd (handle) of the window to capture</param> public static Bitmap Capture(IntPtr handle) { Rectangle bounds; var rect = new Rect(); GetWindowRect(handle, ref rect); bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top); CursorPosition = new Point(Cursor.Position.X - rect.Left, Cursor.Position.Y - rect.Top); var result = new Bitmap(bounds.Width, bounds.Height); using (var g = Graphics.FromImage(result)) g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size); return result; } /// <summary> Position of the cursor relative to the start of the capture </summary> public static Point CursorPosition; /// <summary> Save an image to a specific file </summary> /// <param name="filename">Filename. /// <para>* If extension is omitted, it's calculated from the type of file</para> /// <para>* If path is omitted, defaults to %TEMP%</para> /// <para>* Use %NOW% to put a timestamp in the filename</para></param> /// <param name="format">Optional file save mode. Default is PNG</param> /// <param name="image">Image to save. Usually a BitMap, but can be any /// Image.</param> static void ImageSave(string filename, ImageFormat format, Image image) { format = format ?? ImageFormat.Png; if (!filename.Contains(".")) filename = filename.Trim() + "." + format.ToString().ToLower(); if (!filename.Contains(@"\")) filename = Path.Combine(Environment.GetEnvironmentVariable("TEMP") ?? @"C:\Temp", filename); filename = filename.Replace("%NOW%", DateTime.Now.ToString("yyyy-MM-dd@hh.mm.ss")); image.Save(filename, format); } } } 

这里是捕获桌面或活动窗口的代码片段。 它没有提到Windows窗体。

 public class ScreenCapture { [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern IntPtr GetDesktopWindow(); [StructLayout(LayoutKind.Sequential)] private struct Rect { public int Left; public int Top; public int Right; public int Bottom; } [DllImport("user32.dll")] private static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect); public static Image CaptureDesktop() { return CaptureWindow(GetDesktopWindow()); } public static Bitmap CaptureActiveWindow() { return CaptureWindow(GetForegroundWindow()); } public static Bitmap CaptureWindow(IntPtr handle) { var rect = new Rect(); GetWindowRect(handle, ref rect); var bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top); var result = new Bitmap(bounds.Width, bounds.Height); using (var graphics = Graphics.FromImage(result)) { graphics.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size); } return result; } } 

如何捕捉整个屏幕:

 var image = ScreenCapture.CaptureDesktop(); image.Save(@"C:\temp\snippetsource.jpg", ImageFormat.Jpeg); 

如何捕获活动窗口:

 var image = ScreenCapture.CaptureActiveWindow(); image.Save(@"C:\temp\snippetsource.jpg", ImageFormat.Jpeg); 

最初在这里find: http : //www.snippetsource.net/Snippet/158/capture-screenshot-in-c

我假设你使用Graphics.CopyFromScreen获取屏幕截图。

您可以使用P / Invoke到GetForegroundWindow ( 然后获取其位置和大小 )来确定您需要从哪个区域复制。

你可以使用这个问题的代码: 如何将截图直接保存到Windows中的文件?

只要将WIN32_API.GetDesktopWindow()更改为您要捕获的窗口的Handle属性即可。

稍微调整方法静态无效ImageSave()将授予您select保存它的位置。 信贷转到微软(http://msdn.microsoft.com/en-us/library/sfezx97z.aspx);

 static void ImageSave(string filename, ImageFormat format, Image image, SaveFileDialog saveFileDialog1) { saveFileDialog1.Filter = "JPeg Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif"; saveFileDialog1.Title = "Enregistrer un image"; saveFileDialog1.ShowDialog(); // If the file name is not an empty string open it for saving. if (saveFileDialog1.FileName != "") { // Saves the Image via a FileStream created by the OpenFile method. System.IO.FileStream fs = (System.IO.FileStream)saveFileDialog1.OpenFile(); // Saves the Image in the appropriate ImageFormat based upon the // File type selected in the dialog box. // NOTE that the FilterIndex property is one-based. switch (saveFileDialog1.FilterIndex) { case 1: image.Save(fs, System.Drawing.Imaging.ImageFormat.Jpeg); break; case 2: image.Save(fs, System.Drawing.Imaging.ImageFormat.Bmp); break; case 3: image.Save(fs, System.Drawing.Imaging.ImageFormat.Gif); break; } fs.Close(); } } 

你的button_click事件应该是这样编码的…

 private void btnScreenShot_Click(object sender, EventArgs e) { SaveFileDialog saveFileDialog1 = new SaveFileDialog(); ScreenCapturer.CaptureAndSave(filename, mode, format, saveFileDialog1); }// 

如果你想使用托pipe代码:这将通过ProcessId捕获任何窗口。

我使用以下来使窗口活跃。

 Microsoft.VisualBasic.Interaction.AppActivate(ProcessId); Threading.Thread.Sleep(20); 

我用打印屏幕来捕捉一个窗口。

 SendKeys.SendWait("%{PRTSC}"); Threading.Thread.Sleep(40); IDataObject objData = Clipboard.GetDataObject(); 

使用下面的代码:

  // Shot size = screen size Size shotSize = Screen.PrimaryScreen.Bounds.Size; // the upper left point in the screen to start shot // 0,0 to get the shot from upper left point Point upperScreenPoint = new Point(0, 0); // the upper left point in the image to put the shot Point upperDestinationPoint = new Point(0, 0); // create image to get the shot in it Bitmap shot = new Bitmap(shotSize.Width, shotSize.Height); // new Graphics instance Graphics graphics = Graphics.FromImage(shot); // get the shot by Graphics class graphics.CopyFromScreen(upperScreenPoint, upperDestinationPoint, shotSize); // return the image pictureBox1.Image = shot; 

根据ArsenMkrt的答复,但这个允许你捕获你的窗体中的控件(我正在写一个工具,例如有一个WebBrowser控件,并希望捕获它的显示)。 请注意使用PointToScreen方法:

 //Project: WebCapture //Filename: ScreenshotUtils.cs //Author: George Birbilis (http://zoomicon.com) //Version: 20130820 using System.Drawing; using System.Windows.Forms; namespace WebCapture { public static class ScreenshotUtils { public static Rectangle Offseted(this Rectangle r, Point p) { r.Offset(p); return r; } public static Bitmap GetScreenshot(this Control c) { return GetScreenshot(new Rectangle(c.PointToScreen(Point.Empty), c.Size)); } public static Bitmap GetScreenshot(Rectangle bounds) { Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height); using (Graphics g = Graphics.FromImage(bitmap)) g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size); return bitmap; } public const string DEFAULT_IMAGESAVEFILEDIALOG_TITLE = "Save image"; public const string DEFAULT_IMAGESAVEFILEDIALOG_FILTER = "PNG Image (*.png)|*.png|JPEG Image (*.jpg)|*.jpg|Bitmap Image (*.bmp)|*.bmp|GIF Image (*.gif)|*.gif"; public const string CUSTOMPLACES_COMPUTER = "0AC0837C-BBF8-452A-850D-79D08E667CA7"; public const string CUSTOMPLACES_DESKTOP = "B4BFCC3A-DB2C-424C-B029-7FE99A87C641"; public const string CUSTOMPLACES_DOCUMENTS = "FDD39AD0-238F-46AF-ADB4-6C85480369C7"; public const string CUSTOMPLACES_PICTURES = "33E28130-4E1E-4676-835A-98395C3BC3BB"; public const string CUSTOMPLACES_PUBLICPICTURES = "B6EBFB86-6907-413C-9AF7-4FC2ABF07CC5"; public const string CUSTOMPLACES_RECENT = "AE50C081-EBD2-438A-8655-8A092E34987A"; public static SaveFileDialog GetImageSaveFileDialog( string title = DEFAULT_IMAGESAVEFILEDIALOG_TITLE, string filter = DEFAULT_IMAGESAVEFILEDIALOG_FILTER) { SaveFileDialog dialog = new SaveFileDialog(); dialog.Title = title; dialog.Filter = filter; /* //this seems to throw error on Windows Server 2008 R2, must be for Windows Vista only dialog.CustomPlaces.Add(CUSTOMPLACES_COMPUTER); dialog.CustomPlaces.Add(CUSTOMPLACES_DESKTOP); dialog.CustomPlaces.Add(CUSTOMPLACES_DOCUMENTS); dialog.CustomPlaces.Add(CUSTOMPLACES_PICTURES); dialog.CustomPlaces.Add(CUSTOMPLACES_PUBLICPICTURES); dialog.CustomPlaces.Add(CUSTOMPLACES_RECENT); */ return dialog; } public static void ShowSaveFileDialog(this Image image, IWin32Window owner = null) { using (SaveFileDialog dlg = GetImageSaveFileDialog()) if (dlg.ShowDialog(owner) == DialogResult.OK) image.Save(dlg.FileName); } } } 

有了Bitmap对象,你可以调用Save对象

 private void btnCapture_Click(object sender, EventArgs e) { webBrowser.GetScreenshot().Save("C://test.jpg", ImageFormat.Jpeg); } 

上面假设GC将获取位图,但是最好将someControl.getScreenshot()的结果赋给Bitmapvariables,然后在完成后手动处理该variables,特别是如果你经常这样抓取(比如说你有您想要加载的网页列表并保存其截图):

 private void btnCapture_Click(object sender, EventArgs e) { Bitmap bitmap = webBrowser.GetScreenshot(); bitmap.ShowSaveFileDialog(); bitmap.Dispose(); //release bitmap resources } 

更新:

现在WebCapture工具是ClickOnce-deployed( http://gallery.clipflair.net/WebCapture )从网上(也有很好的自动更新支持感谢ClickOnce),你可以find它的源代码在http://ClipFlair.codeplex.com