.NET TIPS

スクリーンやウィンドウをキャプチャするには?[2.0のみ、C#、VB]

デジタルアドバンテージ 一色 政彦
2006/03/24

 「TIPS:アプリケーション画面のハードコピーを保存するには?」では、プログラムによって[Alt]+[Print Screen]キーを発行して、スクリーン・キャプチャを行う方法を紹介している。このようにキー・ストロークをプログラム的に発行してWindowsシステムにスクリーン(=画面)をキャプチャさせる方法を紹介したのは、.NET Framework 1.xにはスクリーン・キャプチャを行うための機能が搭載されていなかったからだ。

 しかし.NET Framework 2.0ではプログラムから直接、スクリーンをキャプチャするためのメソッドが追加されている。具体的には、次のメソッドである。

 このメソッドを呼び出すと、スクリーンからGraphicsオブジェクトが持つ描画サーフェイスへ、スクリーン・イメージ(=ピクセルの四角形の色データ)を「ビット・ブロック転送」する(いわゆる“BitBlt”)。CopyFromScreenメソッドにはいくつかのオーバーロードが用意されているが、本稿では6つのパラメータを持つバージョンを紹介する。それぞれのパラメータの意味を紹介すると、次のようになる。

  • 第1パラメータ:転送<元>の四角形の左上隅のX座標(int型/Integer型の値)。
  • 第2パラメータ:転送<元>の四角形の左上隅のY座標(int型/Integer型の値)。
  • 第3パラメータ:転送<先>の四角形の左上隅のX座標(int型/Integer型の値)。
  • 第4パラメータ:転送<先>の四角形の左上隅のY座標(int型/Integer型の値)。

  • 第5パラメータ:四角形のサイズ(Size型の値)。
  • 第6パラメータ:スクリーン・イメージ(=ピクセルの四角形の色データ)をビット・ブロック転送する際の方式を指定する(CopyPixelOperation列挙体の値)。CopyPixelOperation列挙体(System.Drawing名前空間)には、そのままコピーする(SourceCopy)だけでなく、例えばコピー元とコピー先の各ピクセルの色をAND演算で組み合わせて出力する(SourceAnd)など、さまざまなオプションが用意されている。詳しくはMSDNの「CopyPixelOperation 列挙体」の説明を参照してほしい。

 単にスクリーン・キャプチャするだけなら、第6パラメータは常に「CopyPixelOperation.SourceCopy」を指定すればよい。

スクリーン・キャプチャを行うサンプル・プログラム

 次の画面は、CopyFromScreenメソッドを利用してスクリーン・キャプチャを行ったサンプル・プログラムの実行例である。このサンプル・プログラムは、キャプチャしたい対象領域をコンボボックスから選択して[キャプチャ]ボタンをクリックすると、その領域をキャプチャしてビットマップ・ファイル(.bmpファイル)として保存したうえで、そのファイルを自動的に開くという仕様になっている。

CopyFromScreenメソッドを利用したサンプル・プログラムの実行例
サンプル・プログラムを実行したところ。このサンプル・プログラムでは、対象領域に対する単純なスクリーン・キャプチャを行い、ビットマップ・ファイル(.bmpファイル)として保存する。
  キャプチャする対象を「スクリーン全体」「フォーム全体」「コンボボックスのみ」「ボタンのみ」から選択する。この例では「フォーム全体」が選択されている。
  [キャプチャ]ボタンをクリックすると、対象領域のスクリーン・キャプチャを行い、ビットマップ・ファイル「C:\screen.bmp」として保存する。
  生成されたビットマップ・ファイルを自動的に開く。なお筆者の環境の例ではWindows XPに付属の「Windows 画像と FAX ビューア」でビットマップ・ファイル(.bmpファイル)が開かれる。

 この実装コード(Clickイベント・ハンドラ部分のみを抜粋)は次のとおりだ。なおソース・コード全体は以下の説明欄にあるリンクからダウンロードできる。

using System.Drawing.Imaging;
using System.Diagnostics;

private void button1_Click(object sender, EventArgs e)
{
  // スクリーン・キャプチャする範囲を決定
  Rectangle rc;
  switch (comboBox1.SelectedItem.ToString())
  {
    case "スクリーン全体":
      rc = Screen.PrimaryScreen.Bounds;
      break;
    case "フォーム全体":
      rc = this.Bounds;
      break;
    case "コンボボックスのみ":
      rc = this.RectangleToScreen(comboBox1.Bounds);
      break;
    case "ボタンのみ":
      rc = this.RectangleToScreen(button1.Bounds);
      break;
    default:
      rc = Screen.PrimaryScreen.WorkingArea;
      break;
  }

  // Bitmapオブジェクトにスクリーン・キャプチャ
  Bitmap bmp = new Bitmap(
    rc.Width, rc.Height, PixelFormat.Format32bppArgb);
  using (Graphics g = Graphics.FromImage(bmp))
  {
    g.CopyFromScreen(rc.X, rc.Y, 0, 0,
      rc.Size, CopyPixelOperation.SourceCopy);

    // ビット・ブロック転送方式の切り替え例:
    //g.FillRectangle(Brushes.LightPink,
    //  0, 0, rc.Width, rc.Height);
    //g.CopyFromScreen(rc.X, rc.Y, 0, 0,
    //  rc.Size, CopyPixelOperation.SourceAnd);
  }

  // ビットマップ画像として保存して表示
  string filePath = @"C:\screen.bmp";
  bmp.Save(filePath, ImageFormat.Bmp);
  Process.Start(filePath);
}
Imports System.Drawing.Imaging
Imports System.Diagnostics

Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click

  ' スクリーン・キャプチャする範囲を決定
  Dim rc As Rectangle
  Select Case comboBox1.SelectedItem.ToString()
    Case "スクリーン全体"
      rc = Screen.PrimaryScreen.Bounds
      Exit Select
    Case "フォーム全体"
      rc = Me.Bounds
      Exit Select
    Case "コンボボックスのみ"
      rc = Me.RectangleToScreen(comboBox1.Bounds)
      Exit Select
    Case "ボタンのみ"
      rc = Me.RectangleToScreen(button1.Bounds)
      Exit Select
    Case Else
      rc = Screen.PrimaryScreen.WorkingArea
      Exit Select
  End Select

  ' Bitmapオブジェクトにスクリーン・キャプチャ
  Dim bmp As New Bitmap( _
    rc.Width, rc.Height, PixelFormat.Format32bppArgb)
  Using g As Graphics = Graphics.FromImage(bmp)

    g.CopyFromScreen(rc.X, rc.Y, 0, 0, _
      rc.Size, CopyPixelOperation.SourceCopy)

    ' ビット・ブロック転送方式の切り替え例:
    'g.FillRectangle(Brushes.LightPink, _
    '  0, 0, rc.Width, rc.Height)
    'g.CopyFromScreen(rc.X, rc.Y, 0, 0, _
    '  rc.Size, CopyPixelOperation.SourceAnd)

  End Using

  ' ビットマップ画像として保存して表示
  Dim filePath As String = "C:\screen.bmp"
  bmp.Save(filePath, ImageFormat.Bmp)
  Process.Start(filePath)

End Sub
CopyFromScreenメソッドを利用したサンプル・プログラムのソース・コード(上:C#、下:VB)
ソース・コード全体のダウンロード(C#版:Form1.cs/VB版:Form1.vb

 このソース・コードは、以下のような実装内容となっている。

 まずコンボボックスで選択された値に基づき、スクリーン領域の座標およびサイズを決定している。ここでのスクリーン全体(≒ディスプレイ解像度)のサイズを取得する方法についての詳細は、「TIPS:ディスプレイの解像度を取得するには?」を参照してほしい。

 またフォームやコントロールなどのウィンドウ領域は、それぞれのBoundsプロパティから取得できるが、詳しくは「TIPS:クライアント領域やウィンドウ領域の座標を取得するには?」を参照していただきたい。なおそこで取得したウィンドウ領域をスクリーン座標系で用いるには、(RectangleToScreenメソッドなどによる)座標変換が必要となる。この座標変換に関しては、「TIPS:スクリーン座標←→クライアント座標の変換を行うには?」を参照されたい。

 次にそのスクリーン領域のサイズに合わせたBitmapオブジェクトを作成し、そのGDI+描画サーフェイス(=Graphicsオブジェクト)を取得して、CopyFromScreenメソッドを使ってそこにスクリーン・イメージをビット・ブロック転送する。

 後はビットマップ画像を保存して表示を行っている。画像の保存に関しては「TIPS:画像をファイルに保存するには?」を、ビットマップ画像の表示に関しては「TIPS:ほかのアプリケーションを実行するには?」を参考にしてほしい。End of Article

利用可能バージョン:.NET Framework 2.0のみ
カテゴリ:クラス・ライブラリ 処理対象:グラフィックス
使用ライブラリ:Graphicsクラス(System.Drawing名前空間)
使用ライブラリ:CopyPixelOperation列挙体(System.Drawing名前空間)
関連TIPS:アプリケーション画面のハードコピーを保存するには?
関連TIPS:ディスプレイの解像度を取得するには?
関連TIPS:クライアント領域やウィンドウ領域の座標を取得するには?
関連TIPS:スクリーン座標←→クライアント座標の変換を行うには?
関連TIPS:画像をファイルに保存するには?
関連TIPS:ほかのアプリケーションを実行するには?
 
この記事と関連性の高い別の.NET TIPS
スクリーン座標←→クライアント座標の変換を行うには?
クライアント領域やウィンドウ領域の座標を取得するには?
ある座標や領域がコントロールの領域内に含まれているかを確認するには?
マウス・カーソルの位置を取得・設定するには?
アプリケーション画面のハードコピーを保存するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間