[win8] Win+Alt+PrtScr でアクティブウィンドウを画面キャプチャする

というのを見つけて、「えーえー、知らないですともッ!!!」ってことで、試してみるとWin8ではマイピクチャ(8.1の場合は「画像」)にスクリーンショット(screenshots)というフォルダに「スクリーンショット (1).png」な感じで画像ファイルが保存されます。

そうなると、Alt+PrtScr と同じように、Win+Alt+PrtScr としたときにアクティブなウィンドウをキャプチャして保存してくれると便利ですよね。実際、手元で似たツールは作っていたのですが、Shift+PrtScr にしていたので、Win+Alt+PrtScr に変えてみます。Shift にしているのは、Visual Studio などの画面キャプチャをするときにメニューが閉じられないので書籍用のキャプチャがしやすい、ってのもあります。Alt を押すとメニューが閉じられてしまうので。

あと、Win+PrtScr の場合は、デュアルディスプレイの場合はすべての画面を一遍にキャプチャしてしまうので、モニタ毎のキャプチャ機能を追加してみます。Win+テンキーの1 にしておきます。本当は「Win+1+PrtScr」にしたかったのですが、「Win+1」のキーはタスクバーの最初のアイコンに割り当てられているので、これは使えません(なんじゃ、こんな機能があったのか、ってな具合ですが)。ちなみに「Win+2」は2番目のアイコンです。あと、「Win+Shift+1」の場合は新しくアプリを立ち上げます。なるほど。

ホットキーの設定あたりは、

Ctrl+PrintScreen でアクティブなウィンドウをキャプチャする – Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/2344

を参考にして、そのまま写し。

あとはついでだけど、リモートコンピュータに対しての画面キャプチャも

リモートコンピュータの画面をキャプチャする – Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/3352

まあ、リモートコンピュータ(タブレットPC)の場合は、Mouse without Borders を入れておけば良いのですが。

複数モニタに対応する部分だけコードを示しておきます。
プライマリモニタ(最初のモニタ)は、Screen.PrimaryScreen で取得できるので、これから Bounds を使ってサイズを取得。CopyFromScreen で全体の画面キャプチャから切り出しをすれば ok です。
サブモニタや3枚目のモニタの場合は、Screen.AllScreens で取ればいいですね。モニタ位置は Bounds の Left と Top で撮れるので切り出しをします。

/// <summary>
/// 指定モニタをキャプチャ
/// </summary>
/// <param name="num"></param>
/// <returns></returns>
private Bitmap ScreenCapture(int num)
{
    if (0 < num &&  num - 1 < Screen.AllScreens.Count())
    {
        Screen sc = Screen.AllScreens[num - 1];
        int width = sc.Bounds.Width;
        int height = sc.Bounds.Height;
        Bitmap bmp = new Bitmap(width, height);
        Graphics g = Graphics.FromImage(bmp);
        // モニタ位置を考慮する。
        g.CopyFromScreen( sc.Bounds.Left, sc.Bounds.Top, 0, 0, bmp.Size);
        return bmp;
    }
    else
    {
        // 最初の画面をキャプチャ
        int width = Screen.PrimaryScreen.Bounds.Width;
        int height = Screen.PrimaryScreen.Bounds.Height;
        Bitmap bmp = new Bitmap(width, height);
        Graphics g = Graphics.FromImage(bmp);
        g.CopyFromScreen(0, 0, 0, 0, bmp.Size);
        return bmp;
    }
}

あとは、かなりダサい方法ですが、マイピクチャに連番で保存すればOKです。正規表現を使ってもいいのですが、まあ、これで用途は足りているので。

/// <summary>
/// マイピクチャへ保存
/// </summary>
/// <param name="bmp"></param>
void SaveToMyPictures(Bitmap bmp)
{
    string folder = System.Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
    folder += @"Screenshots";
    // マッチする一覧を取得
    int num = 0;
    var files = System.IO.Directory.GetFiles(folder, "スクリーンショット (*");
    if (files.Count() == 0)
    {
        num = 1;
    }
    else
    {
        var nums = files.Select(f =>
            int.Parse(
            f.Replace( folder, "" )
                .Replace("スクリーンショット (", "")
                .Replace(").png", "")));
        num = nums.Max();
        num++;
    }
    string path = string.Format("{0}スクリーンショット ({1}).png", folder, num);
    bmp.Save(path);
}

実験用なのでホットキーを設定するボタンがありますが、起動時に自動的に登録すれば ok です。

サンプルはこちらに。
http://sdrv.ms/15kdFTs

# ああ、Windows 7 の場合でも使えるようにバージョンチェックしてフォルダ作って、というのも考えていたのですが、作るの忘れていました。それは別の機会に。

カテゴリー: C# パーマリンク