コマンドラインから画面キャプチャーを実行して
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)を作成する前に、すべてのモニターの情報を得て、各モニターの左上、右下の座標位置からデスクトップ全体の解像度を求めている部分のみで、そのあとの処理はシングルモニターの場合と一緒だ。
この連載の記事
-
第458回
PC
Windows上でhostsファイルを活用する -
第457回
PC
IPv6アドレスは先頭を見ればどんな種類かわかる -
第456回
PC
あらためてIPv6基本のキ -
第455回
PC
Windowsで現在どのネットワークアダプタがインターネット接続に使われているかを調べる方法 -
第454回
PC
Windows 11 24H2では「デバイスの暗号化」の条件が変わり、より多くのPCでドライブが暗号化される -
第453回
PC
Windows 11 24H2の配布開始後もすぐにはやってこない Windows UpdateとSafeguard Holds -
第452回
PC
Windows 11 Ver.24H2が登場 Copilot+ PCとそうでないPCで実質Windowsが2つに分かれる -
第451回
PC
新しいWindowsサンドボックスではコマンドラインからの制御が可能に -
第450回
PC
ユニコードで文字数を数える方法 -
第449回
PC
WSLはプレビュー版でGUIでの設定が加わった! リリース2.3.xの新機能を見る -
第448回
PC
PowerShellで面倒なオブジェクトはPSCustomObjectに変換するのが早道 - この連載の一覧へ