C# 将屏幕捕获到位图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/362986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Capture the Screen into a Bitmap
提问by Omar Abid
I want to capture the screen in my code to get an image - like using the 'print screen' button on the keyboard .
我想在我的代码中捕获屏幕以获取图像 - 就像使用键盘上的“打印屏幕”按钮一样。
Does anyone have an idea how to do this? I have no starting point.
有谁知道如何做到这一点?我没有起点。
采纳答案by Gary Willoughby
If using the .NET 2.0 (or later) framework you can use the CopyFromScreen()
method detailed here:
如果使用 .NET 2.0(或更高版本)框架,您可以使用CopyFromScreen()
此处详述的方法:
http://www.geekpedia.com/tutorial181_Capturing-screenshots-using-Csharp.html
http://www.geekpedia.com/tutorial181_Capturing-screenshots-using-Csharp.html
//Create a new bitmap.
var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
PixelFormat.Format32bppArgb);
// Create a graphics object from the bitmap.
var 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("Screenshot.png", ImageFormat.Png);
回答by Skhanpara
// Use this version to capture the full extended desktop (i.e. multiple screens)
Bitmap screenshot = new Bitmap(SystemInformation.VirtualScreen.Width,
SystemInformation.VirtualScreen.Height,
PixelFormat.Format32bppArgb);
Graphics screenGraph = Graphics.FromImage(screenshot);
screenGraph.CopyFromScreen(SystemInformation.VirtualScreen.X,
SystemInformation.VirtualScreen.Y,
0,
0,
SystemInformation.VirtualScreen.Size,
CopyPixelOperation.SourceCopy);
screenshot.Save("Screenshot.png", System.Drawing.Imaging.ImageFormat.Png);
回答by user4340666
回答by trung thong hoang
Bitmap memoryImage;
//Set full width, height for image
memoryImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
PixelFormat.Format32bppArgb);
Size s = new Size(memoryImage.Width, memoryImage.Height);
Graphics memoryGraphics = Graphics.FromImage(memoryImage);
memoryGraphics.CopyFromScreen(0, 0, 0, 0, s);
string str = "";
try
{
str = string.Format(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +
@"\Screenshot.png");//Set folder to save image
}
catch { };
memoryImage.save(str);
回答by colton7909
I had two problems with the accepted answer.
我对接受的答案有两个问题。
- It doesn't capture all screens in a multi-monitor setup.
- The width and height returned by the
Screen
class are incorrect when display scaling is used and your application is not declared dpiAware.
- 它不会在多显示器设置中捕获所有屏幕。
Screen
当使用显示缩放并且您的应用程序未声明为dpiAware时,类返回的宽度和高度不正确。
Here's my updated solution using the Screen.AllScreens
static property and calling EnumDisplaySettings
using p/invoke to get the real screen resolution.
这是我使用Screen.AllScreens
静态属性并EnumDisplaySettings
使用 p/invoke 调用以获得真实屏幕分辨率的更新解决方案。
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
class Program
{
const int ENUM_CURRENT_SETTINGS = -1;
static void Main()
{
foreach (Screen screen in Screen.AllScreens)
{
DEVMODE dm = new DEVMODE();
dm.dmSize = (short)Marshal.SizeOf(typeof(DEVMODE));
EnumDisplaySettings(screen.DeviceName, ENUM_CURRENT_SETTINGS, ref dm);
using (Bitmap bmp = new Bitmap(dm.dmPelsWidth, dm.dmPelsHeight))
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(dm.dmPositionX, dm.dmPositionY, 0, 0, bmp.Size);
bmp.Save(screen.DeviceName.Split('\').Last() + ".png");
}
}
}
[DllImport("user32.dll")]
public static extern bool EnumDisplaySettings(string lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode);
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
private const int CCHDEVICENAME = 0x20;
private const int CCHFORMNAME = 0x20;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public int dmPositionX;
public int dmPositionY;
public ScreenOrientation dmDisplayOrientation;
public int dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmFormName;
public short dmLogPixels;
public int dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
}
}
References:
参考:
https://stackoverflow.com/a/36864741/987968http://pinvoke.net/default.aspx/user32/EnumDisplaySettings.html?diff=y
https://stackoverflow.com/a/36864741/987968 http://pinvoke.net/default.aspx/user32/EnumDisplaySettings.html?diff=y