.NET開発者のためのブログメディア

C#での画面キャプチャの取得方法を徹底解説!
- SE
- 画面キャプチャについて詳しく教えてください。
- PM
- 画面キャプチャ、もしくはスクリーンショットとも呼ばれていますね。では実際のソースコード見ながら理解を深めていきましょう。
目次
C#での画面キャプチャについて
今回は、C#での画面キャプチャについて説明します。
スクリーン全体のキャプチャ、アクティブウィンドウのキャプチャ、矩形領域のキャプチャの方法をソースコードとともに紹介します。
C#での画面キャプチャに興味のある方はぜひご覧ください。
スクリーン全体の画面キャプチャ
C#では、スクリーン全体の画面キャプチャが取得できます。プライマリスクリーンのサイズを取得し、画面キャプチャを取得しましょう。
実際のソースコードを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
using System; using System.Drawing; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : Form { Button button1; PictureBox pictureBox; public Form1() { InitializeComponent(); this.AutoScroll = true; this.Load += Form1_Load; } private void Form1_Load(object sender, EventArgs e) { button1 = new Button(); button1.Location = new Point(10, 10); button1.Text = “画面全体”; button1.AutoSize = true; button1.Click += Button1_Click; pictureBox = new PictureBox(); pictureBox.Location = new Point(10, 40); pictureBox.SizeMode = PictureBoxSizeMode.AutoSize; this.Controls.Add(button1); this.Controls.Add(pictureBox); } private void Button1_Click(object sender, EventArgs e) { // プライマリスクリーン全体 Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Graphics graphics = Graphics.FromImage(bitmap); // 画面全体をコピーする graphics.CopyFromScreen(new Point(0, 0), new Point(0, 0), bitmap.Size); // グラフィックスの解放 graphics.Dispose(); //表示 pictureBox.Image = bitmap; } } } |
“画面全体”ボタンをクリックすると、プライマリスクリーンの画面キャプチャがFormに表示されます。
このように、C#ではスクリーン全体の画面キャプチャが取得できます。
アクティブウィンドウの画面キャプチャ
C#では、アクティブウィンドウの画面キャプチャが取得できます。
実際のソースコードを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
using System; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; namespace WindowsFormsApp1 { public partial class Form1 : Form { Button button1; PictureBox pictureBox; [StructLayout(LayoutKind.Sequential)] private struct Rect { public int left; public int top; public int right; public int bottom; } [DllImport(“user32.Dll”)] static extern int GetWindowRect(IntPtr hWnd, out Rect rect); [DllImport(“user32.dll”)] extern static IntPtr GetForegroundWindow(); public Form1() { InitializeComponent(); this.AutoScroll = true; this.Load += Form1_Load; } private void Form1_Load(object sender, EventArgs e) { button1 = new Button(); button1.Location = new Point(10, 10); button1.Text = “アクティブウィンドウ”; button1.AutoSize = true; button1.Click += Button1_Click; pictureBox = new PictureBox(); pictureBox.Location = new Point(10, 40); pictureBox.SizeMode = PictureBoxSizeMode.AutoSize; this.Controls.Add(button1); this.Controls.Add(pictureBox); } private void Button1_Click(object sender, EventArgs e) { Rect rect; // アクティブウィンドウを取得 IntPtr activeWindow = GetForegroundWindow(); GetWindowRect(activeWindow, out rect); Rectangle rectangle = new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); Bitmap bitmap = new Bitmap(rectangle.Width, rectangle.Height); Graphics graphics = Graphics.FromImage(bitmap); // 画面をコピー graphics.CopyFromScreen(new Point(rectangle.X, rectangle.Y), new Point(0, 0), rectangle.Size); // 表示 pictureBox.Image = bitmap; } } } |
“アクティブウィンドウ”ボタンをクリックすると、Form自体の画面キャプチャがFormに表示されます。
Windows Vista以降のOSの場合、Form外の領域も若干キャプチャされています。
このように、C#ではアクティブウィンドウの画面キャプチャが取得できます。
アクティブウィンドウの画面キャプチャ その2
先ほどのサンプルでは、OSによってはForm外の領域も若干キャプチャされていました。
DwmGetWindowAttributeでDWMWA_EXTENDED_FRAME_BOUNDSを指定すれば、改善できます。
実際のソースコードを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
using System; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; namespace WindowsFormsApp1 { public partial class Form1 : Form { private const int SRCCOPY = 13369376; private const int DWMWA_EXTENDED_FRAME_BOUNDS = 9; Button button1; PictureBox pictureBox; [StructLayout(LayoutKind.Sequential)] private struct Rect { public int left; public int top; public int right; public int bottom; } [DllImport(“user32.dll”)] static extern IntPtr GetWindowRect(IntPtr hWnd, out Rect rect); [DllImport(“user32.dll”)] extern static IntPtr GetForegroundWindow(); [DllImport(“dwmapi.dll”)] extern static int DwmGetWindowAttribute(IntPtr hWnd, int dwAttribute, out Rect rect, int cbAttribute); [DllImport(“user32.dll”)] static extern IntPtr GetWindowDC(IntPtr hWnd); [DllImport(“gdi32.dll”)] static extern int BitBlt(IntPtr hDestDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop); [DllImport(“user32.dll”)] static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hdc); public Form1() { InitializeComponent(); this.AutoScroll = true; this.Load += Form1_Load; } private void Form1_Load(object sender, EventArgs e) { button1 = new Button(); button1.Location = new Point(10, 10); button1.Text = “アクティブウィンドウ”; button1.AutoSize = true; button1.Click += Button1_Click; pictureBox = new PictureBox(); pictureBox.Location = new Point(10, 40); pictureBox.SizeMode = PictureBoxSizeMode.AutoSize; this.Controls.Add(button1); this.Controls.Add(pictureBox); } private void Button1_Click(object sender, EventArgs e) { Rect bounds, rect; // アクティブウィンドウを取得 IntPtr hWnd = GetForegroundWindow(); IntPtr winDC = GetWindowDC(hWnd); DwmGetWindowAttribute(hWnd, DWMWA_EXTENDED_FRAME_BOUNDS, out bounds, Marshal.SizeOf(typeof(Rect))); GetWindowRect(hWnd, out rect); var offsetX = bounds.left - rect.left; var offsetY = bounds.top - rect.top; Bitmap bitmap = new Bitmap(bounds.right - bounds.left, bounds.bottom - bounds.top); Graphics graphics = Graphics.FromImage(bitmap); IntPtr hDC = graphics.GetHdc(); BitBlt(hDC, 0, 0, bitmap.Width, bitmap.Height, winDC, offsetX, offsetY, SRCCOPY); graphics.ReleaseHdc(hDC); graphics.Dispose(); ReleaseDC(hWnd, winDC); // 表示 pictureBox.Image = bitmap; } } } |
“アクティブウィンドウ”ボタンをクリックすると、Form自体の画面キャプチャがFormに表示されます。
先ほどのサンプルのような、Form外の領域がキャプチャされないことが分かります。
このように、C#ではアクティブウィンドウの画面キャプチャが取得できます。
矩形領域の画面キャプチャ
C#では、矩形領域の画面キャプチャが取得できます。
実際のソースコードを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
using System; using System.Drawing; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : Form { Button button1; PictureBox pictureBox; public Form1() { InitializeComponent(); this.AutoScroll = true; this.Load += Form1_Load; } private void Form1_Load(object sender, EventArgs e) { button1 = new Button(); button1.Location = new Point(10, 10); button1.Text = “矩形領域”; button1.AutoSize = true; button1.Click += Button1_Click; pictureBox = new PictureBox(); pictureBox.Location = new Point(10, 40); pictureBox.SizeMode = PictureBoxSizeMode.AutoSize; this.Controls.Add(button1); this.Controls.Add(pictureBox); } private void Button1_Click(object sender, EventArgs e) { // 矩形領域 Rectangle rectangle = new Rectangle(200, 200, 800, 500); Bitmap bitmap = new Bitmap(rectangle.Width, rectangle.Height); Graphics graphics = Graphics.FromImage(bitmap); graphics.CopyFromScreen(new Point(rectangle.X, rectangle.Y), new Point(0, 0), bitmap.Size); // グラフィックスの解放 graphics.Dispose(); //表示 pictureBox.Image = bitmap; } } } |
“矩形領域”ボタンをクリックすると、(200, 200)の座標から横800pixel、縦500pixelの矩形領域の画面キャプチャがFormに表示されます。
このように、C#では矩形領域の画面キャプチャが取得できます。
- SE
- 画面全体の他に領域を指定した画面キャプチャ方法もあるんですね。
- PM
- ここまで見てきたソースコードを応用して、より理解を深めていってください。
C#で画面キャプチャの取得をしよう
いかがでしたでしょうか。C#での、スクリーン全体、アクティブウィンドウ、矩形領域などの画面キャプチャ方法についてご紹介しました。
今回紹介した画面キャプチャのサンプルを応用すれば、Snipping Toolのようなアプリを作れます。
ぜひご自身でソースコードを書いて、理解を深めてみましょう。