ここではカーソルをカラーカーソルにして大きさも変更しました。ところがこれをスクリーンキャプチャしようとしてもうまくいきませんでした。
マウスカーソルはPrtScキーを押してもキャプチャされません。よくやる方法が以下の方法です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
private void ScreenCapture() { Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Graphics g = Graphics.FromImage(bmp); //画面全体をコピーする g.CopyFromScreen(new Point(0, 0), new Point(0, 0), bmp.Size); // カーソルを書き込む Cursor.DrawStretched(g, new Rectangle(Control.MousePosition, Cursor.Size)); g.Dispose(); Clipboard.SetImage(bmp); return; } |
しかしカーソルの色は保存されますが、サイズは拡大する前の大きさです。Cursor.Sizeプロパティをつかってもサイズは反映されていません。Cursor.Sizeでカーソルのサイズが正しく取得できないのでこれではうまくいかないのは当然です。
そこで別の方法を考えます。
下の方法はAPI関数GetIconInfo関数を用いてカーソルからビットマップを取得して、その大きさを調べています。
1 2 3 4 5 6 7 8 9 10 11 12 |
public class CursorEx { static public Size GetCursorSize(Cursor cursor) { IconInfo tmp = new IconInfo(); GetIconInfo(cursor.Handle, ref tmp); Bitmap bitmap = Bitmap.FromHbitmap(tmp.hbmColor); Size size = bitmap.Size; bitmap.Dispose(); return size; } } |
CursorExクラス全体は
を参照してください。
これなら以下の方法でキャプチャできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
private void ScreenCapture() { Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Graphics g = Graphics.FromImage(bmp); g.CopyFromScreen(new Point(0, 0), new Point(0, 0), bmp.Size); // カーソルを書き込む Cursor.DrawStretched(g, new Rectangle(Control.MousePosition, CursorEx.GetCursorSize(this.Cursor))); g.Dispose(); // クリップボードへ Clipboard.SetImage(bmp); return; } |
ところでもうひとつ問題があります。マウスカーソルを大きくすると影のような四角い境界線がみえてしまうことです。
原因は、元の画像の座標系の原点が画素の中心部分にあるからです。
この問題は、最初にビットマップ全体を透明にしたい色で塗りつぶすことで解消できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
static public Cursor GetCursorFromImage(Image image, Size size, int HotspotX, int HotspotY, Color transparent) { Bitmap bitmap = new Bitmap(size.Width, size.Height); Graphics g = Graphics.FromImage(bitmap); // 透明にしたい色で塗りつぶす(この2行を追加した) SolidBrush brush = new SolidBrush(transparent); g.FillRectangle(brush, 0, 0, size.Width, size.Height); // ここから下は同じ g.DrawImage(image, new Rectangle(0, 0, size.Width, size.Height)); bitmap.MakeTransparent(transparent); Icon tempCursor = Icon.FromHandle(bitmap.GetHicon()); bitmap.Dispose(); g.Dispose(); IconInfo tmp = new IconInfo(); GetIconInfo(tempCursor.Handle, ref tmp); tmp.fIcon = false; tmp.xHotspot = HotspotX; tmp.yHotspot = HotspotY; IntPtr ptr = CreateIconIndirect(ref tmp); tempCursor.Dispose(); return new Cursor(ptr); } |