web-dev-qa-db-ja.com

画面をビットマップにキャプチャする

キーボードの[画面の印刷]ボタンを使用するように、コードで画面をキャプチャして画像を取得します。

誰もこれを行う方法を知っていますか?出発点がありません。

61
Omar Abid

.NET 2.0(またはそれ以降)フレームワークを使用している場合、ここで詳細に説明されている CopyFromScreen() メソッドを使用できます。

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);
105
Gary Willoughby
// 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);
6
Skhanpara

受け入れられた答えには2つの問題がありました。

  1. マルチモニター設定ですべての画面をキャプチャするわけではありません。
  2. ディスプレイスケーリングが使用され、アプリケーションが dpiAware として宣言されていない場合、Screenクラスによって返される幅と高さは正しくありません。

Screen.AllScreens静的プロパティを使用し、p/invokeを使用してEnumDisplaySettingsを呼び出して実際の画面解像度を取得する、更新されたソリューションを次に示します。

using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace CaptureScreenshots
{
    class Program
    {
        const int ENUM_CURRENT_SETTINGS = -1;

        static void Main(string[] args)
        {
            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;
        }
    }
}

参照:

https://stackoverflow.com/a/36864741/987968http://pinvoke.net/default.aspx/user32/EnumDisplaySettings.html?diff=y

2
colton7909

this コードを試してください

Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics gr = Graphics.FromImage(bmp);
gr.CopyFromScreen(0, 0, 0, 0, bmp.Size);
pictureBox1.Image = bmp;
bmp.Save("img.png",System.Drawing.Imaging.ImageFormat.Png);
1
user4340666
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);
0