このページの本文へ

前へ 1 2 次へ

Windows Info 第327回

Windowsでコマンドラインから画面キャプチャーをする

2022年05月15日 10時00分更新

文● 塩田紳二 編集● ASCII

  • この記事をはてなブックマークに追加
  • 本文印刷

コマンド一発というわけにはいかないが、Windowsではコマンドラインからも画面キャプチャーが可能だ

コマンドラインから画面キャプチャーを実行して
PNG形式で保存する

 画面キャプチャー(スクリーンショットとも)は、ソフトウェアのドキュメント作成やメモ代わりにすることが多い。こうしたとき、コマンドラインから画面キャプチャーをしたくなることがあるが、残念ながら、Windowsには直接可能なコマンドは用意されていない。しかし、PowerShellを使えば、まったく不可能というわけではない。

 まず画面が1つだけ、マルチディスプレイではない環境で、デスクトップ全体の画面キャプチャーをする方法を考える。

 最初に、PowerShellでSystem.Windows.FormsとSystem.Drawingクラスを使えるように以下のコマンドを実行しておく。PowerShellのウィンドウを閉じるまでに1回だけ実行しておけばよい。複数のキャプチャー方式を解説するが、どの方法でも、このAdd-Typeコマンドを事前に実行していなければならない。

Add-Type -AssemblyName System.Windows.Forms,System.Drawing

 次にディスプレイの解像度(=デスクトップのピクセル単位の縦横のサイズ)を調べる。それには、

$sc=[Windows.Forms.Screen]::PrimaryScreen

とする。もちろん、マシンスペックなどから1920×1080であると決めつけても構わないが、上記のコマンドなら環境に関わりなく、デスクトップの解像度が得られる(マルチディスプレイ環境では、通知領域のあるプライマリモニターが対象)。もっとも実際に得られるのは、サイズなどの情報を含んだ「Screen」オブジェクトである。

 次に、これを使って、キャプチャー画像を保存するためのbitmapオブジェクト(System.Drawing.bitmap)を作る。それには、

$bmp=New-Object System.Drawing.Bitmap $sc.Bounds.width,$sc.Bounds.height

とする。もし解像度を決め打ちするのであれば、以下のように直接数値を指定してもかまわない。

$bmp=New-Object System.Drawing.Bitmap 1920,1080

 これで画像の保存先ができた。実際に画面キャプチャーをするには、以下のコマンドを実行する。

([System.Drawing.Graphics]::FromImage($bmp)).CopyFromscreen(0,0,0,0,$bmp.size)

 なお、キャプチャーはこのコマンドを実行した瞬間にされるが、この前に「start-sleep 10;」を前置すれば10秒後に、「pause ;」や「[Console]::ReadKey() | Out-Null ;」などを置けばキー入力待ちのあとに実行される。

 作成したビットマップをファイルとして保存すれば、Windowsのアプリケーションなどで扱える。それには、

$bmp.Save("C:\temp\P$(get-date -Format 'yyyyMMdd-hhmmss').png")

とする。ただし、上記のコマンドは、C:\Tempに文字Pで始まり、日時が続くファイル名のPNG画像を保存するものだ。なお、このコマンドではファイル形式はPNGに限られる。キャプチャーを繰り返すなら、ビットマップはそのまま利用でき、作り直す必要はない。CopyFromscreenとSaveのみ再度実行すればよい。

 最後に作成したビットマップのリソースを開放しメモリを空ける。

$bmp.Dispose()

とすることで、メモリを専有していたビットマップデータが削除される。

 マルチディスプレイの場合には、ちょっと手間が増える。デスクトップの解像度を計算して求める必要があるからだ。その場合のコマンドを以下に示す。

Add-Type -AssemblyName System.Windows.Forms,System.Drawing $screens = [Windows.Forms.Screen]::AllScreens

$desktop=[Drawing.Rectangle]::FromLTRB(
    [System.Linq.Enumerable]::Min([int[]]$screens.Bounds.Left),
    [System.Linq.Enumerable]::Min([int[]]$screens.Bounds.Top),
    [System.Linq.Enumerable]::Max([int[]]$screens.Bounds.Right),
    [System.Linq.Enumerable]::Max([int[]]$screens.Bounds.Bottom)
)

$bmp=New-Object System.Drawing.Bitmap $desktop.width,$desktop.height
([System.Drawing.Graphics]::FromImage($bmp)).CopyFromscreen($desktop.left,$desktop.top,0,0,$bmp.size)

 違いは、ビットマップ($bmp)を作成する前に、すべてのモニターの情報を得て、各モニターの左上、右下の座標位置からデスクトップ全体の解像度を求めている部分のみで、そのあとの処理はシングルモニターの場合と一緒だ。

前へ 1 2 次へ

カテゴリートップへ

この連載の記事

注目ニュース

ASCII倶楽部

プレミアムPC試用レポート

ピックアップ

ASCII.jp RSS2.0 配信中

ASCII.jpメール デジタルMac/iPodマガジン