画面をキャプチャする画面をキャプチャ(ハードコピー)し、イメージをBitmapオブジェクトとして取得する方法を幾つか紹介します。 Print Screenキーストロークを送信する方法最も簡単な方法は、Print ScreenキーストロークをSendKeys.SendWait(またはSend)メソッドで送信し、クリップボードにコピーされたイメージを取得する方法です。Ctrl+PrintScreenキーストローク("^{PRTSC}")で画面全体がキャプチャされ、Alt+PrintScreenキーストローク("%{PRTSC}")でアクティブなウィンドウがキャプチャされます(PrintScreenキーストロークのみでもアクティブなウィンドウがキャプチャされるようです)。 ただしこの方法では確実に画面のイメージを取得できる保障はありません(実際に失敗することも多いようです)。 SendKeysに関しては、「VB6のSendKeysと同じ事を行うには?」もご覧ください。 補足:MSDNの「SendKeys.Send メソッド」には、「{PRTSC} (今後使用するために予約されている)」と書かれています。 この方法により画面全体のイメージを取得し、PictureBox(PictureBox1)に表示するサンプルを以下に示します。 [VB.NET] '画面全体のイメージをクリップボードにコピー SendKeys.SendWait("^{PRTSC}") '次のようにすると、アクティブなウィンドウのイメージをコピー 'SendKeys.SendWait("{PRTSC}") 'SendKeys.SendWait("%{PRTSC}") 'DoEventsを呼び出したほうがよい場合があるらしい 'Application.DoEvents() 'クリップボードにあるデータの取得 Dim d As IDataObject = Clipboard.GetDataObject() 'ビットマップデータ形式に関連付けられているデータを取得 Dim img As Image = CType(d.GetData(DataFormats.Bitmap), Image) If Not (img Is Nothing) Then 'データが取得できたときはPictureBoxに表示する PictureBox1.Image = img '画面のイメージデータは大きいため、 '用がなくなればクリップボードから削除した方がいいかもしれない Clipboard.SetDataObject(New DataObject) End If [C#] //画面全体のイメージをクリップボードにコピー SendKeys.SendWait("^{PRTSC}"); //次のようにすると、アクティブなウィンドウのイメージをコピー //SendKeys.SendWait("{PRTSC}"); //SendKeys.SendWait("%{PRTSC}"); //DoEventsを呼び出したほうがよい場合があるらしい //Application.DoEvents(); //クリップボードにあるデータの取得 IDataObject d = Clipboard.GetDataObject(); //ビットマップデータ形式に関連付けられているデータを取得 Image img = (Image) d.GetData(DataFormats.Bitmap); if (img != null) { //データが取得できたときはPictureBoxに表示する PictureBox1.Image = img; //画面のイメージデータは大きいため、 //用がなくなればクリップボードから削除した方がいいかもしれない Clipboard.SetDataObject(new DataObject()); } Win32 APIを使用する方法ちゃんとした画面キャプチャを行うには、Win32 APIを使うことになります。この方法関しては、ウェブ上で優れたサンプルがいくつも公開されています。その一部を紹介します。 以下はC#のサンプルです。
以下はVB.NETのサンプルです。 以下に画面全体をキャプチャするメソッド(CaptureScreen)と、アクティブなウィンドウをキャプチャするメソッド(CaptureActiveWindow)のごく簡単なサンプルを紹介します。 [VB.NET] 'Imports System.Runtime.InteropServices 'がソースファイルの一番上に書かれているものとする Const SRCCOPY As Integer = 13369376 <DllImport("user32.dll")> _ Private Shared Function GetDC(ByVal hwnd As IntPtr) As IntPtr End Function <DllImport("gdi32.dll")> _ Private Shared Function BitBlt(ByVal hDestDC As IntPtr, _ ByVal x As Integer, ByVal y As Integer, _ ByVal nWidth As Integer, ByVal nHeight As Integer, _ ByVal hSrcDC As IntPtr, _ ByVal xSrc As Integer, ByVal ySrc As Integer, _ ByVal dwRop As Integer) As Integer End Function <DllImport("user32.dll")> _ Private Shared Function ReleaseDC(ByVal hwnd As IntPtr, _ ByVal hdc As IntPtr) As IntPtr End Function ''' <summary> ''' プライマリスクリーンの画像を取得する ''' </summary> ''' <returns>プライマリスクリーンの画像</returns> Public Shared Function CaptureScreen() As Bitmap 'プライマリモニタのデバイスコンテキストを取得 Dim disDC As IntPtr = GetDC(IntPtr.Zero) 'Bitmapの作成 Dim bmp As New Bitmap(Screen.PrimaryScreen.Bounds.Width, _ Screen.PrimaryScreen.Bounds.Height) 'Graphicsの作成 Dim g As Graphics = Graphics.FromImage(bmp) 'Graphicsのデバイスコンテキストを取得 Dim hDC As IntPtr = g.GetHdc() 'Bitmapに画像をコピーする BitBlt(hDC, 0, 0, bmp.Width, bmp.Height, disDC, 0, 0, SRCCOPY) '解放 g.ReleaseHdc(hDC) g.Dispose() ReleaseDC(IntPtr.Zero, disDC) Return bmp End Function <StructLayout(LayoutKind.Sequential)> _ Private Structure RECT Public left As Integer Public top As Integer Public right As Integer Public bottom As Integer End Structure <DllImport("user32.dll")> _ Private Shared Function GetWindowDC(ByVal hwnd As IntPtr) As IntPtr End Function <DllImport("user32.dll")> _ Private Shared Function GetForegroundWindow() As IntPtr End Function <DllImport("user32.dll")> _ Private Shared Function GetWindowRect(ByVal hwnd As IntPtr, _ ByRef lpRect As RECT) As Integer End Function ''' <summary> ''' アクティブなウィンドウの画像を取得する ''' </summary> ''' <returns>アクティブなウィンドウの画像</returns> Public Shared Function CaptureActiveWindow() As Bitmap 'アクティブなウィンドウのデバイスコンテキストを取得 Dim hWnd As IntPtr = GetForegroundWindow() Dim winDC As IntPtr = GetWindowDC(hWnd) 'ウィンドウの大きさを取得 Dim winRect As New RECT GetWindowRect(hWnd, winRect) 'Bitmapの作成 Dim bmp As New Bitmap(winRect.right - winRect.left, _ winRect.bottom - winRect.top) 'Graphicsの作成 Dim g As Graphics = Graphics.FromImage(bmp) 'Graphicsのデバイスコンテキストを取得 Dim hDC As IntPtr = g.GetHdc() 'Bitmapに画像をコピーする BitBlt(hDC, 0, 0, bmp.Width, bmp.Height, winDC, 0, 0, SRCCOPY) '解放 g.ReleaseHdc(hDC) g.Dispose() ReleaseDC(hWnd, winDC) Return bmp End Function [C#] //using System.Runtime.InteropServices; //がソースファイルの一番上に書かれているものとする private const int SRCCOPY = 13369376; [DllImport("user32.dll")] private static extern IntPtr GetDC(IntPtr hwnd); [DllImport("gdi32.dll")] private 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")] private static extern IntPtr ReleaseDC(IntPtr hwnd, IntPtr hdc); /// <summary> /// プライマリスクリーンの画像を取得する /// </summary> /// <returns>プライマリスクリーンの画像</returns> public static Bitmap CaptureScreen() { //プライマリモニタのデバイスコンテキストを取得 IntPtr disDC = GetDC(IntPtr.Zero); //Bitmapの作成 Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); //Graphicsの作成 Graphics g = Graphics.FromImage(bmp); //Graphicsのデバイスコンテキストを取得 IntPtr hDC = g.GetHdc(); //Bitmapに画像をコピーする BitBlt(hDC, 0, 0, bmp.Width, bmp.Height, disDC, 0, 0, SRCCOPY); //解放 g.ReleaseHdc(hDC); g.Dispose(); ReleaseDC(IntPtr.Zero, disDC); return bmp; } [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 GetWindowDC(IntPtr hwnd); [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] private static extern int GetWindowRect(IntPtr hwnd, ref RECT lpRect); /// <summary> /// アクティブなウィンドウの画像を取得する /// </summary> /// <returns>アクティブなウィンドウの画像</returns> public static Bitmap CaptureActiveWindow() { //アクティブなウィンドウのデバイスコンテキストを取得 IntPtr hWnd = GetForegroundWindow(); IntPtr winDC = GetWindowDC(hWnd); //ウィンドウの大きさを取得 RECT winRect = new RECT(); GetWindowRect(hWnd, ref winRect); //Bitmapの作成 Bitmap bmp = new Bitmap(winRect.right - winRect.left, winRect.bottom - winRect.top); //Graphicsの作成 Graphics g = Graphics.FromImage(bmp); //Graphicsのデバイスコンテキストを取得 IntPtr hDC = g.GetHdc(); //Bitmapに画像をコピーする BitBlt(hDC, 0, 0, bmp.Width, bmp.Height, winDC, 0, 0, SRCCOPY); //解放 g.ReleaseHdc(hDC); g.Dispose(); ReleaseDC(hWnd, winDC); return bmp; } .NET Framework 2.0以降で、Graphics.CopyFromScreenメソッドを使用する方法.NET Framework 2.0から追加されたGraphics.CopyFromScreenメソッドを使用すれば、画面上の指定された範囲をキャプチャすることができます。 画面全体をキャプチャしてPictureBox1に表示する例を以下に示します。 [VB.NET] 'Bitmapの作成 Dim bmp As New Bitmap(Screen.PrimaryScreen.Bounds.Width, _ Screen.PrimaryScreen.Bounds.Height) 'Graphicsの作成 Dim g As Graphics = Graphics.FromImage(bmp) '画面全体をコピーする g.CopyFromScreen(New Point(0, 0), New Point(0, 0), bmp.Size) '解放 g.Dispose() '表示 PictureBox1.Image = bmp [C#] //Bitmapの作成 Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); //Graphicsの作成 Graphics g = Graphics.FromImage(bmp); //画面全体をコピーする g.CopyFromScreen(new Point(0, 0), new Point(0, 0), bmp.Size); //解放 g.Dispose(); //表示 PictureBox1.Image = bmp;
(この記事は、「.NETプログラミング研究 第53号」で紹介したものを基にしています。) |
|
Copyright 2002-2008 DOBON!. All rights reserved.
|