[OS] Win10, Windowsでコマンドラインから画面キャプチャー
Windows Info ― 第327回
Windowsでコマンドラインから画面キャプチャーをする
塩田紳二
2022年05月15日 10時00分更新
コマンド一発というわけにはいかないが、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)を作成する前に、すべてのモニターの情報を得て、各モニターの左上、右下の座標位置からデスクトップ全体の解像度を求めている部分のみで、そのあとの処理はシングルモニターの場合と一緒だ。
ASCII.jp
https://ascii.jp/elem/000/004/091/4091532/
0 件のコメント:
コメントを投稿