blog.kur.jp

バイオリンと山、自転車をこよなく愛するkurのチラシの裏。たまには技術的なことを書いたりするかも知れません。

CopyFromScreenでスクリーンショットを取得

以前から開発しているITR-Recorderというソフトがある。このソフトでは、プログラムからウィンドウのスクリーンショットを撮るで書いたような方法でウィンドウのスクリーンショットを取得していたんだけど、スクリーンショットを撮る方法は他にもある、という情報を得たので軽く実装してみた。

この方法ではユーザから見た画面をキャプチャすることしかできない。つまりキャプチャしたいウィンドウより前に他のウィンドウがあると、それを含めてキャプチャされてしまうので、特定のウィンドウを確実にキャプチャしたい場合は、そのウィンドウをアクティブにする必要があるということ。それが出来ない場合はこの方法は使えないので注意。

[csharp] using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.Drawing.Imaging; using System.Diagnostics; using System.Runtime.InteropServices;

namespace copyfromscr { struct RECT { public int left; public int top; public int right; public int bottom; } class Program { [DllImport("User32.dll")] public extern static bool GetWindowRect(IntPtr hWnd, out RECT rect);

    static RECT rect;
    static void Main(string[] args)
    {
        Bitmap CurrentImg;
        Process Firefox;
        Firefox = GetProcessOf("firefox");
        CurrentImg = GetScreenCaputureOf(Firefox);
        CurrentImg.Save(@"C:\aaa\hoge.png");
    }

    // 指定されたプロセスを取得
    static Process GetProcessOf(string ProcessName)
    {
        foreach (Process p in Process.GetProcesses())
        {
            if (p.MainWindowHandle != IntPtr.Zero)
            {
                //プロセスの名前がfirefoxのもののみ処理
                if (p.ProcessName == ProcessName)
                {
                    return p;
                }
            }
        }
        return null;
    }
    // 指定されたプロセスのキャプチャを取得.失敗したらnull
    static Bitmap GetScreenCaputureOf(Process p)
    {
        Bitmap img;
        if (GetWindowRect(p.MainWindowHandle, out rect))
        {
            img = new Bitmap((rect.right - rect.left), (rect.bottom - rect.top));
            using (Graphics g = Graphics.FromImage(img)){
                g.CopyFromScreen(new Point(rect.left, rect.top), new Point(0, 0), img.Size);
            }
        }
        else
        {
            img = null;
        }
        return img;
    }
}

} [/csharp]