ฉันกำลังสร้างแอปพลิเคชั่นจับภาพหน้าจอและทุกอย่างกำลังดี สิ่งที่ฉันต้องทำคือจับหน้าต่างที่ใช้งานอยู่และจับภาพหน้าจอของหน้าต่างที่ใช้งานอยู่นี้ ไม่มีใครรู้ว่าฉันสามารถทำสิ่งนี้ได้อย่างไร
ฉันกำลังสร้างแอปพลิเคชั่นจับภาพหน้าจอและทุกอย่างกำลังดี สิ่งที่ฉันต้องทำคือจับหน้าต่างที่ใช้งานอยู่และจับภาพหน้าจอของหน้าต่างที่ใช้งานอยู่นี้ ไม่มีใครรู้ว่าฉันสามารถทำสิ่งนี้ได้อย่างไร
คำตอบ:
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);
}
ฉันขอแนะนำวิธีแก้ไขปัญหาต่อไปสำหรับการจับภาพหน้าต่างที่ใช้งานอยู่ในปัจจุบัน (ไม่เพียง แต่แอปพลิเคชัน C # ของเรา) หรือทั้งหน้าจอที่มีการกำหนดตำแหน่งเคอร์เซอร์เทียบกับมุมซ้ายบนของหน้าต่างหรือหน้าจอตามลำดับ
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;
}
}
Rect
ด้วย System ของฉันRectangle
แต่หลังจากนั้นฟังก์ชั่นGetWindowRect
กลับผิดรูปสี่เหลี่ยมผืนผ้า แทนที่จะเป็นRight
และTop
มันตั้งค่าWidth
และHeight
ของสี่เหลี่ยมออก
var thisWindowHandle = new WindowInteropHelper(Application.Current.MainWindow).Handle;
แทน
นี่คือตัวอย่างการจับภาพเดสก์ท็อปหรือหน้าต่างที่ใช้งานอยู่ ไม่มีการอ้างอิงถึง Windows Forms
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);
แต่เดิมพบได้ที่นี่: http://www.snippetsource.net/Snippet/158/capture-sc Screenshot-in-c
รหัสของ KvanTTT ใช้งานได้ดีมาก ฉันขยายออกไปเล็กน้อยเพื่อให้มีความยืดหยุ่นเพิ่มขึ้นเล็กน้อยในรูปแบบการบันทึกเช่นเดียวกับความสามารถในการบันทึกโดย hWnd, .NET Control / Form คุณสามารถรับบิตแมปหรือบันทึกเป็นไฟล์โดยมีตัวเลือกให้เลือก
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);
}
}
}
ฉันถือว่าคุณใช้Graphics.CopyFromScreen
เพื่อรับภาพหน้าจอ
คุณสามารถใช้P / เรียกใช้เพื่อ GetForegroundWindow ( จากนั้นรับตำแหน่งและขนาด ) เพื่อกำหนดภูมิภาคที่คุณต้องการคัดลอก
คุณสามารถใช้รหัสจากคำถามนี้: ฉันจะบันทึกภาพหน้าจอไปยังไฟล์ใน Windows ได้อย่างไร?
เพียงเปลี่ยนWIN32_API.GetDesktopWindow()
เป็นคุณสมบัติการจัดการของหน้าต่างที่คุณต้องการดักจับ
การปรับแต่งเล็กน้อยไปยังวิธีการโมฆะ ImageSave ()จะช่วยให้คุณมีตัวเลือกที่จะบันทึก เครดิตไปที่ Microsoft (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);
}//
หากคุณต้องการใช้รหัสที่ได้รับการจัดการ: สิ่งนี้จะดักจับหน้าต่างใด ๆ ผ่านทาง 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 แต่อันนี้อนุญาตให้คุณจับตัวควบคุมในแบบฟอร์มของคุณ (ฉันกำลังเขียนเครื่องมือสำหรับตัวอย่างที่มีเว็บเบราเซอร์ควบคุมอยู่ในนั้นและต้องการจับเฉพาะจอแสดงผลของมัน) สังเกตการใช้งานของ 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);
}
}
}
มีวัตถุบิตแมปที่คุณสามารถเรียกบันทึกบนมัน
private void btnCapture_Click(object sender, EventArgs e)
{
webBrowser.GetScreenshot().Save("C://test.jpg", ImageFormat.Jpeg);
}
ข้างต้นสมมติว่า GC จะจับบิตแมป แต่อาจเป็นการดีกว่าที่จะกำหนดผลลัพธ์ของ someControl.getSc แอฟริกา () ให้กับตัวแปรบิตแมปจากนั้นกำจัดตัวแปรนั้นด้วยตนเองเมื่อเสร็จสิ้นแต่ละภาพโดยเฉพาะอย่างยิ่งถ้าคุณกำลังทำสิ่งนี้บ่อยครั้ง ( บอกว่าคุณมีรายการหน้าเว็บที่คุณต้องการโหลดและบันทึกภาพหน้าจอของพวกเขา):
private void btnCapture_Click(object sender, EventArgs e)
{
Bitmap bitmap = webBrowser.GetScreenshot();
bitmap.ShowSaveFileDialog();
bitmap.Dispose(); //release bitmap resources
}
ยิ่งไปกว่านั้นสามารถใช้ use clause ซึ่งมีประโยชน์เพิ่มเติมจากการปล่อยทรัพยากรบิตแมปแม้ในกรณีที่มีข้อยกเว้นเกิดขึ้นในบล็อก use (child):
private void btnCapture_Click(object sender, EventArgs e)
{
using(Bitmap bitmap = webBrowser.GetScreenshot())
bitmap.ShowSaveFileDialog();
//exit from using block will release bitmap resources even if exception occured
}
ปรับปรุง:
ตอนนี้เครื่องมือ WebCapture เป็น ClickOnce-deployed ( http://gallery.clipflair.net/WebCapture ) จากเว็บ (ยังมีการสนับสนุน autoupdate ที่ดีขอบคุณ ClickOnce) และคุณสามารถค้นหาซอร์สโค้ดได้ที่https://github.com/Zoomicon / ClipFlair / ต้น / Master / เซิร์ฟเวอร์ / เครื่องมือ / WebCapture