C# 如何获取表单的屏幕截图
是否有任何方法可以输出活动窗体的屏幕截图?请尝试以下操作:C# 如何获取表单的屏幕截图,c#,.net,winforms,C#,.net,Winforms,是否有任何方法可以输出活动窗体的屏幕截图?请尝试以下操作: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Drawing.Imaging; namespace ScreenshotCapt
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
namespace ScreenshotCapturer
{
public partial class Form1 : Form
{
private static Bitmap bmpScreenshot;
private static Graphics gfxScreenshot;
public Form1()
{
InitializeComponent();
}
private void btnCapture_Click(object sender, EventArgs e)
{
// If the user has choosed a path where to save the screenshot
if (saveScreenshot.ShowDialog() == DialogResult.OK)
{
// Hide the form so that it does not appear in the screenshot
this.Hide();
// Set the bitmap object to the size of the screen
bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
// Create a graphics object from the bitmap
gfxScreenshot = Graphics.FromImage(bmpScreenshot);
// Take the screenshot from the upper left corner to the right bottom corner
gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
// Save the screenshot to the specified path that the user has chosen
bmpScreenshot.Save(saveScreenshot.FileName, ImageFormat.Png);
// Show the form again
this.Show();
}
}
}
}
以下是您可以使用的扩展方法:
#region Interop
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr hdc, PRF_FLAGS drawingOptions);
const uint WM_PRINT = 0x317;
[Flags]
enum PRF_FLAGS : uint
{
CHECKVISIBLE = 0x01,
CHILDREN = 0x02,
CLIENT = 0x04,
ERASEBKGND = 0x08,
NONCLIENT = 0x10,
OWNED = 0x20
}
#endregion
public static Image CaptureImage(this Control control)
{
Image img = new Bitmap(control.Width, control.Height);
using (Graphics g = Graphics.FromImage(img))
{
SendMessage(
control.Handle,
WM_PRINT,
g.GetHdc(),
PRF_FLAGS.CLIENT | PRF_FLAGS.NONCLIENT | PRF_FLAGS.ERASEBKGND);
}
return img;
}
表单
继承自控件
,因此您也可以在表单上使用它。更简单的答案是.NET支持的:
.使用Control.DrawToBitmap()方法。例如:
private void timer1_Tick(object sender, EventArgs e) {
var frm = Form.ActiveForm;
using (var bmp = new Bitmap(frm.Width, frm.Height)) {
frm.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
bmp.Save(@"c:\temp\screenshot.png");
}
}
现在
gr.Save(@"c\pic.jpg",ImageFormat.jpg);
这会将活动窗口的屏幕截图保存到C:驱动器中
SendKeys.Send(“”)
用于将按键发送到计算机。在这种情况下,%
用于按Alt
和{PRTSC}
显然用于按键盘上的打印屏幕
按钮
希望这对别人有帮助
private void printScreenButton_Click(object sender, EventArgs e)
{
SendKeys.Send("%{PRTSC}");
Image img = Clipboard.GetImage();
img.Save(@"C:\\testprintscreen.jpg");
}
因为Control.DrawToBitmap有一些限制(最明显的是以相反的顺序绘制子控件),所以我做了这个选择。变量
\u control
是要复制的WinForms控件/窗体
using (Bitmap bitmap = new Bitmap(width, height)) {
using (Graphics gb = Graphics.FromImage(bitmap))
using (Graphics gc = Graphics.FromHwnd(_control.Handle)) {
IntPtr hdcDest = IntPtr.Zero;
IntPtr hdcSrc = IntPtr.Zero;
try {
hdcDest = gb.GetHdc();
hdcSrc = gc.GetHdc();
BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRC_COPY);
} finally {
if (hdcDest != IntPtr.Zero) gb.ReleaseHdc(hdcDest);
if (hdcSrc != IntPtr.Zero) gc.ReleaseHdc(hdcSrc);
}
}
bitmap.Save(...);
}
[DllImport("gdi32.dll", EntryPoint = "BitBlt")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool BitBlt(
[In()] System.IntPtr hdc, int x, int y, int cx, int cy,
[In()] System.IntPtr hdcSrc, int x1, int y1, uint rop);
private const int SRC_COPY = 0xCC0020;
这个截屏课程来自哪里?它不是.NET框架的一部分…我相信您没有读到这个问题。问题状态为“活动窗体的屏幕截图”,而您的解决方案捕获整个屏幕,而不显示活动窗体。我相信你可以很容易地将它转换为问题要求的内容。如果你想捕获当时可能打开的任何对话框,该怎么办?或重叠形式。我认为,你不会看到应用程序在用户屏幕上的真实状态。这种方法有一些限制(最明显的是子控件是按相反顺序绘制的),我发布了一个没有这个问题的答案。它的功能似乎与Control.DrawToBitmap相同,但也有相同的限制(就像以相反的顺序绘制子控件一样)。它还会破坏剪贴板上保存的任何内容,这可能会妨碍用户的操作。
here is:
public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter
[DllImport("gdi32.dll")]
public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest,
int nWidth, int nHeight, IntPtr hObjectSource,
int nXSrc, int nYSrc, int dwRop);
[DllImport("gdi32.dll")]
public static extern bool StretchBlt(
IntPtr hdcDest, // handle to destination DC
int nXOriginDest, // x-coord of destination upper-left corner
int nYOriginDest, // y-coord of destination upper-left corner
int nWidthDest, // width of destination rectangle
int nHeightDest, // height of destination rectangle
IntPtr hdcSrc, // handle to source DC
int nXOriginSrc, // x-coord of source upper-left corner
int nYOriginSrc, // y-coord of source upper-left corner
int nWidthSrc, // width of source rectangle
int nHeightSrc, // height of source rectangle
int dwRop // raster operation code
);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth,
int nHeight);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
private void run_test()
{
Rectangle rc = new Rectangle();
Image img = ScreenToImage(ref rc, false);
img.Save(@"C:\Users\ssaamm\Desktop\Capt44ure.JPG", System.Drawing.Imaging.ImageFormat.Jpeg);
img.Dispose();
}
private Image ScreenToImage(ref Rectangle rcDest, bool IsPapaer)
{
IntPtr handle = this.Handle;
//this.Handle
// get te hDC of the target window
IntPtr hdcSrc = GetWindowDC(handle);
// get the size
RECT windowRect = new RECT();
GetWindowRect(handle, ref windowRect);
int nWidth = windowRect.right - windowRect.left;
int nHeight = windowRect.bottom - windowRect.top;
if (IsPapaer)
{
float fRate = (float)rcDest.Width / nWidth;
//float fHeight = nHeight * fRate;
//rcDest.Height = (int)(nHeight * fRate);
//rcDest.Width = (int)(rcDest.Width);// * fRate);
rcDest.X = 0;
rcDest.Y = 0;
rcDest.Height = (int)(nHeight * fRate);
//rcDest.Width = (int)(nWidth * fRate);
}
else
{
rcDest.X = 0;
rcDest.Y = 0;
rcDest.Height = nHeight;
rcDest.Width = nWidth;
}
// create a device context we can copy to
IntPtr hdcDest = CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = CreateCompatibleBitmap(hdcSrc, rcDest.Width, rcDest.Height);
// select the bitmap object
IntPtr hOld = SelectObject(hdcDest, hBitmap);
// bitblt over
StretchBlt(hdcDest, rcDest.X, rcDest.Y, rcDest.Width, rcDest.Height, hdcSrc, 0, 0, nWidth, nHeight, SRCCOPY);
// restore selection
SelectObject(hdcDest, hOld);
// clean up
DeleteDC(hdcDest);
ReleaseDC(handle, hdcSrc);
// get a .NET image object for it
Image img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
DeleteObject(hBitmap);
return img;
}
using (Bitmap bitmap = new Bitmap(width, height)) {
using (Graphics gb = Graphics.FromImage(bitmap))
using (Graphics gc = Graphics.FromHwnd(_control.Handle)) {
IntPtr hdcDest = IntPtr.Zero;
IntPtr hdcSrc = IntPtr.Zero;
try {
hdcDest = gb.GetHdc();
hdcSrc = gc.GetHdc();
BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRC_COPY);
} finally {
if (hdcDest != IntPtr.Zero) gb.ReleaseHdc(hdcDest);
if (hdcSrc != IntPtr.Zero) gc.ReleaseHdc(hdcSrc);
}
}
bitmap.Save(...);
}
[DllImport("gdi32.dll", EntryPoint = "BitBlt")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool BitBlt(
[In()] System.IntPtr hdc, int x, int y, int cx, int cy,
[In()] System.IntPtr hdcSrc, int x1, int y1, uint rop);
private const int SRC_COPY = 0xCC0020;