フォーム、コントロールの外観をキャプチャするここでは、コントロール(フォームを含む)の外観を画像としてキャプチャする方法を紹介します。なお、画面全体をキャプチャする方法は、「画面をキャプチャする」で紹介しています。 .NET Framework 2.0以降で、Control.DrawToBitmapメソッドを使用する方法.NET Framework 2.0からは、ControlクラスにDrawToBitmapメソッドが追加され、これを使ってコントロールをキャプチャすることができます。 この方法では、キャプチャするコントロールの上に別の(子コントロールでない)コントロールがかぶさっていたり、フォームが別のフォームの下にあったりしても、問題なくキャプチャされます。Visibleがfalseであるコントロールでも、キャプチャできます(ただし、TextBoxはだめ)。 このメソッドでは、RichTextBoxでは正常にキャプチャできません(RichTextBoxが配置されているフォームをキャプチャしても、RichTextBoxは正常に描画されません)。WebBrowserクラスなどでも正常にキャプチャできないようです。また、大きなサイズの画像としてはキャプチャできません。その他の制限については、ヘルプの「Control.DrawToBitmap メソッド」をご覧ください。 下の例では、コードの書かれたフォームの外観をキャプチャして、ファイルに保存しています。 [VB.NET] 'コントロールの外観を描画するBitmapの作成 Dim bmp As New Bitmap(Me.Width, Me.Height) 'キャプチャする Me.DrawToBitmap(bmp, New Rectangle(0, 0, Me.Width, Me.Height)) 'ファイルに保存する bmp.Save("C:\test.png") '後始末 bmp.Dispose() [C#] //コントロールの外観を描画するBitmapの作成 Bitmap bmp = new Bitmap(this.Width, this.Height); //キャプチャする this.DrawToBitmap(bmp, new Rectangle(0, 0, this.Width, this.Height)); //ファイルに保存する bmp.Save("C:\\test.png"); //後始末 bmp.Dispose(); Win32 APIを使用した方法次にWin32 APIを使用した方法を紹介します。以下に示すCaptureControlメソッドは、指定されたコントロールのクライアント領域をキャプチャして、Bitmapオブジェクトとして返します。 この方法では、Control.DrawToBitmapメソッドによる方法と違い、キャプチャするフォームやコントロールが別のフォームなどで隠れていると、正常にキャプチャされません(画面で見たままの状態でキャプチャされます)。
[VB.NET]
<System.Runtime.InteropServices.DllImport("gdi32.dll")> _
Private Shared Function BitBlt(ByVal hdcDest As IntPtr, _
ByVal nXDest As Integer, ByVal nYDest As Integer, _
ByVal nWidth As Integer, ByVal nHeight As Integer, _
ByVal hdcSrc As IntPtr, _
ByVal nXSrc As Integer, ByVal nYSrc As Integer, _
ByVal dwRop As Integer) As Boolean
End Function
Private Const SRCCOPY As Integer = &HCC0020
'フォームのイメージを取得する
Public Function CaptureControl(ByVal ctrl As Control) As Bitmap
Dim g As Graphics = ctrl.CreateGraphics()
Dim img As New Bitmap(ctrl.ClientRectangle.Width, _
ctrl.ClientRectangle.Height, g)
Dim memg As Graphics = Graphics.FromImage(img)
Dim dc1 As IntPtr = g.GetHdc()
Dim dc2 As IntPtr = memg.GetHdc()
BitBlt(dc2, 0, 0, img.Width, img.Height, dc1, 0, 0, SRCCOPY)
g.ReleaseHdc(dc1)
memg.ReleaseHdc(dc2)
memg.Dispose()
g.Dispose()
Return img
End Function
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'コントロールの外観を描画するBitmapの作成
Dim bmp As Bitmap = CaptureControl(Me)
'キャプチャする
bmp.Save("C:\test.png")
'後始末
bmp.Dispose()
End Sub
[C#]
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
private static extern bool BitBlt(IntPtr hdcDest,
int nXDest, int nYDest, int nWidth, int nHeight,
IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
private const int SRCCOPY = 0xCC0020;
/// <summary>
/// コントロールのイメージを取得する
/// </summary>
/// <param name="ctrl">キャプチャするコントロール</param>
/// <returns>取得できたイメージ</returns>
public Bitmap CaptureControl(Control ctrl)
{
Graphics g = ctrl.CreateGraphics();
Bitmap img = new Bitmap(ctrl.ClientRectangle.Width,
ctrl.ClientRectangle.Height, g);
Graphics memg = Graphics.FromImage(img);
IntPtr dc1 = g.GetHdc();
IntPtr dc2 = memg.GetHdc();
BitBlt(dc2, 0, 0, img.Width, img.Height, dc1, 0, 0, SRCCOPY);
g.ReleaseHdc(dc1);
memg.ReleaseHdc(dc2);
memg.Dispose();
g.Dispose();
return img;
}
//Button1のClickイベントハンドラ
private void Button1_Click(object sender, EventArgs e)
{
//コントロールの外観を描画するBitmapの作成
Bitmap bmp = CaptureControl(this);
//キャプチャする
bmp.Save("C:\\test.png");
//後始末
bmp.Dispose();
}
PrintWindow関数Windows XP以上であれば、PrintWindow関数を使ってキャプチャすることもできます。この場合は、キャプチャするフォームやコントロールが別のフォームなどの隠れていても、きちんとキャプチャできます。
[VB.NET]
<System.Runtime.InteropServices.DllImport("User32.dll")> _
Private Shared Function PrintWindow(ByVal hwnd As IntPtr, _
ByVal hDC As IntPtr, ByVal nFlags As Integer) As Boolean
End Function
''' <summary>
''' コントロールのイメージを取得する
''' </summary>
''' <param name="ctrl">キャプチャするコントロール</param>
''' <returns>取得できたイメージ</returns>
Public Function CaptureControl(ByVal ctrl As Control) As Bitmap
Dim img As New Bitmap(ctrl.Width, ctrl.Height)
Dim memg As Graphics = Graphics.FromImage(img)
Dim dc As IntPtr = memg.GetHdc()
PrintWindow(ctrl.Handle, dc, 0)
memg.ReleaseHdc(dc)
memg.Dispose()
Return img
End Function
[C#]
[System.Runtime.InteropServices.DllImport("User32.dll")]
private extern static bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);
/// <summary>
/// コントロールのイメージを取得する
/// </summary>
/// <param name="ctrl">キャプチャするコントロール</param>
/// <returns>取得できたイメージ</returns>
public Bitmap CaptureControl(Control ctrl)
{
Bitmap img = new Bitmap(ctrl.Width, ctrl.Height);
Graphics memg = Graphics.FromImage(img);
IntPtr dc = memg.GetHdc();
PrintWindow(ctrl.Handle, dc, 0);
memg.ReleaseHdc(dc);
memg.Dispose();
return img;
}
ピクチャボックスに表示されている画像を取得するInvokePaintメソッド、及びInvokePaintBackgroundメソッドを使ってPictureBoxに表示されている画像を取得する方法を紹介します。この方法で取得できる画像は、PictureBoxのPaintイベント、及びPaintBackgroundイベントでPaintEventArgs.Graphicsに描画された画像だけです。具体的には、PictureBoxのImageプロパティ、BackGroundImageプロパティ、BackColorプロパティで指定された画像や、PaintイベントハンドラでPaintEventArgs.Graphicsを使って描画された画像などに限られます。 以下に、この方法によりPictureBox(PictureBox1)に表示されている画像を画像ファイルに保存する方法を示します。 [VB.NET] 'PictureBox1の大きさを取得 Dim rect As Rectangle = PictureBox1.ClientRectangle 'PictureBox1に表示されている画像を取得するためのBitmap Dim bmp As New Bitmap(rect.Width, rect.Height) 'bmpに画像を入れるための準備 Dim g As Graphics = Graphics.FromImage(bmp) Dim pea As New PaintEventArgs(g, rect) 'PaintBackgroundイベントを発生 Me.InvokePaintBackground(PictureBox1, pea) 'Paintイベントを発生 Me.InvokePaint(PictureBox1, pea) '画像を保存する bmp.Save("C:\test.png") '後始末 g.Dispose() bmp.Dispose() [C#] //PictureBox1の大きさを取得 Rectangle rect = PictureBox1.ClientRectangle; //PictureBox1に表示されている画像を取得するためのBitmap Bitmap bmp = new Bitmap(rect.Width, rect.Height); //bmpに画像を入れるための準備 Graphics g = Graphics.FromImage(bmp); PaintEventArgs pea = new PaintEventArgs(g, rect); //PaintBackgroundイベントを発生 this.InvokePaintBackground(PictureBox1, pea); //Paintイベントを発生 this.InvokePaint(PictureBox1, pea); //画像を保存する bmp.Save(@"C:\test.png"); //後始末 g.Dispose(); bmp.Dispose(); この方法により外見を画像として取得できるコントロールは、あまりありません。PictureBox以外に、Label、Button、DataGridコントロール等でうまく行くようですが、FlatStyleプロパティがSystemの時は失敗します。 Print Screenキーでキャプチャする方法フォームをキャプチャする方法として、フォームをアクティブにしてから、Alt+PrintScreenキーストロークを送信する方法も考えられます。これについては、「画面をキャプチャする」をご覧ください。
(この記事は、「.NETプログラミング研究 第46号」で紹介したものを基にしています。) |
|
Copyright 2002-2008 DOBON!. All rights reserved.
|