パソコンの画面をスクショしたい時、どうしていますか?
私は、Windows に標準で搭載されている「Snipping Tool」を使っています。このアプリはパソコンに表示されている画面を画像として取り込むことができます。パソコンの全画面を取り込むか、指定した部分の範囲だけを取り込むかなどモードを選択して用途に合わせた使い方ができます。下図は Windows 11の「Snipping Tool」です。
取り込んだ画像は画像ファイルとして保存できるのですが、Windows 10までの「Snipping Tool」は自動保存に対応していませんでした。大量に画像をスクショする場合は、毎回 [ファイル] -> [名前を付けて保存] からファイル名を指定する必要がありました。この作業が結構面倒で、自動で保存できれば楽になるな~と使う度に思っていました。
そこで今回は、WPF でパソコンに表示されている画面をスクリーンショットして、自動で画像ファイルとして保存するアプリを作成してみようと思います。
※Windows 11の「Snipping Tool」なら設定から自動保存を有効にすれば、スクショした画像を Picture フォルダの スクリーンショットフォルダへ自動で保存してくれます。
アプリのイメージ
アプリで実現したいことは次の2つです。この記事では紹介していませんが、モード(全画面、ウィンドウ、範囲指定)の切り替え機能や画像にテキストを挿入したり、テキストの編集ができる機能も欲しいところですが、ここでは欲張らないことにします。
[jin_icon_check color=”#e9546b” size=”14px”] スクショできること(この記事では指定した範囲だけを切り取る)
[jin_icon_check color=”#e9546b” size=”14px”] 自動保存できること
この2つの機能を実現するアプリのイメージ図を簡単に書いてみました。
赤枠内のスクショエリアは透明になっているので、ウィンドウを移動したりサイズ変更をしてスクショしたい画面の範囲を調整します。
その後、スクショボタンをクリックしてスクショエリアの画面を取り込んで画像ファイルを保存先のフォルダへ保存するようにします。
アプリ作成
Visual Studio を起動して、[ファイル] -> [新規作成] -> [プロジェクト]の順に選択して、WPFのテンプレートでプロジェクトを作成します。
XAMLで画面を作る
ウィンドウのスクショエリアの背景だけを透明にします。
WPF ではウィンドウの3つのプロパティを次のように設定すれば、全部の背景を透明にすることができます。
[jin_icon_checkcircle color=”#e9546b” size=”14px”] Background プロパティを”Transparent”にする。
[jin_icon_checkcircle color=”#e9546b” size=”14px”] WindowStyle プロパティを”None”にする。
[jin_icon_checkcircle color=”#e9546b” size=”14px”] AllowsTransparency プロパティを”True”にする。
ここで注意したいのが、ウィンドウの”全背景”を透明にするので、透明にしたくない部分は Grid や Panel などで色づけしなければなりません。
アプリ画面については、こちらの記事で紹介しているウィンドウにテキストボックスとボタンを追加して使うことにします。XAML の記述は以下から確認をしてみて下さい。
アプリ画面は下図のようになりました。スクショボタンには Click イベントを登録しておいてください。これで画面作成は終わりです。
System.Drawing.Commonをインストールする
パソコンの画面に表示されている画面を画像として取り込む時に、System.Drawing 名前空間に定義されている Bitmap を利用します。
ただし、フレームワークが .NET Core で System.Drawing を利用する際は、System.Drawing.Common への明示的なアセンブリの参照追加が必要になります。この System.Drawing.Common は NuGet からインストールしてアセンブリの参照へ追加することができます。
Visual Studio 上でソリューションエクスプローラーを開いて、[依存関係] -> [NuGetパッケージの管理] の順に選択をして NuGetパッケージ マネージャーを開きます。
ウィンドウの上部にある[参照]タブを選択(1)して、すぐ下にある検索ボックスに「System.Drawing.Common」と入力して検索(2)します。
検索にヒットした候補から「System.Drawing.Common」を選択(3)して、[インストール]ボタンをクリックして最新の安定版をインストール(4)します。
コードを書く
次の2つの名前空間を使うので、using ディレクティブに追加します。
using System.Drawing;
using System.Drawing.Imaging;
スクショエリアの範囲で画面を撮影して、画像ファイルとして保存するまでの関数を作成します。関数の引数にはスクショエリアの範囲とファイルパスを指定します。処理の流れは次の通りです。
① 引数の矩形(rect)と同じサイズのBitmapを作成する
② 引数の矩形(rect)と同じ条件(座標・サイズ)で画面をコピーする
③ BitmapのSaveメソッドで画像ファイルとして保存する
アプリ画面にあるスクショボタンをクリックすると、スクリーンショットと保存されるようにコードを記述します。
private void btnSnap_Click(object sender, RoutedEventArgs e)
{
// スクショエリアの座標を取得
var targetPoint = this.brdScreen.PointToScreen(new System.Windows.Point(0.0d, 0.0d));
// キャプチャ領域の生成
var targetRect = new Rect(targetPoint.X, targetPoint.Y, this.brdScreen.ActualWidth, this.brdScreen.ActualHeight);
// スクリーンショット実行
ExcuteScreenShot(targetRect, fileName(txtFolderPath.Text));
}
private string fileName(string folderPath)
{
var dtNow = DateTime.Now;
var file = dtNow.ToString("yyyyMMdd_hhmmss") + dtNow.Millisecond.ToString() + ".jpg";
return Path.Combine(folderPath, file);
}
private void ExcuteScreenShot(Rect rect, string fileName)
{
// 矩形と同じサイズのBitmapを作成
using (var bitmap = new Bitmap((int)rect.Width, (int)rect.Height))
using (var graphics = Graphics.FromImage(bitmap))
{
// 画面から指定された矩形と同じ条件でコピー
graphics.CopyFromScreen((int)rect.X, (int)rect.Y, 0, 0, bitmap.Size);
// 画像ファイルとして保存
bitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
スクショエリアは、brdScreen(borderコントロール)の枠内になるので、スクショボタンがクリックされた時点でのbrdScreenの座標とサイズを指定すれば、その矩形領域でスクリーンショットできることになります。
アプリの動作確認
Visual Studioのデバックを実行してアプリを起動します。
スクショしたい箇所へアプリの画面を移動して大きさを調整してから、スクショボタンを押してみて下さい。
画像ファイルの保管先を開いて、画像ファイルが保存されていれば成功です。
まとめ
この記事ではスクリーンショットした画面を画像ファイルとして、任意のフォルダへ自動で保存するアプリを作成しました。
System.DrawingのBitmapを使うことで、指定した範囲の画面コピーと保存までできるので意外と簡単に実装することができました。
以上、最後まで読んで頂きありがとうございました。