http://blog.csdn.net/manimanihome/article/details/2071517
C#截取屏幕中選定區域的圖像
原理:主窗體首先截取整個屏幕圖像作為主窗體的背景圖,並且最大化,然後再做一個可調整大小的半透明窗體,將該窗體顯示在主窗體上,那麼該窗體所在的方框就是所要截取的方框.調整該窗体也就可以調整截取的范圍.
1.主窗體的設計
相關屬性:
this.TopMost = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
--1.截取整個屏幕圖像
private Bitmap GetScreenImage()
{
Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
Graphics g = Graphics.FromImage(bmp);
g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size);
g.Dispose();
return bmp;
}
--2.畫方框
private void FormBack_MouseMove(object sender, MouseEventArgs e)
{
if (!this.catcher.Visible)
{
this.label_CatcherLoc.Text = "位置 X: " + e.X + ", Y: " + e.Y;
}
if (this.isMouseLeftDown)
{
Rectangle rect = new Rectangle();
rect.X = e.X > this.catcherLoc.X ? this.catcherLoc.X : e.X;
rect.Y = e.Y > this.catcherLoc.Y ? this.catcherLoc.Y : e.Y;
rect.Width = Math.Abs(e.X - this.catcherLoc.X);
rect.Height = Math.Abs(e.Y - this.catcherLoc.Y);
this.catcher.Bounds = rect;
if (!this.catcher.Visible)
{
this.catcher.Show(this);
}
}
}
--3.取消繪製或退出:
private void FormBack_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
if (!this.catcher.Visible)
{
Application.Exit();
}
else
{
this.catcher.Visible = false;
this.catcherLoc = Point.Empty;
this.isMouseLeftDown = false;
}
}
else if (e.Button == MouseButtons.Left)
{
if (!this.catcher.Visible)
{
this.catcherLoc = e.Location;
this.isMouseLeftDown = true;
}
}
}
--4.調整顯示面板
如果改成(左上-->右上-->右下-->左下),代碼也不難,效果應該更好.
private void panel_Info_MouseEnter(object sender, EventArgs e)
{
Panel pl = (Panel)sender;
if (pl.Right < this.Width / 2)//在左邊
{
pl.Location = new Point(this.Width - pl.Width - 20, pl.Location.Y);
}
else
{
pl.Location = new Point(10, 10);
}
}
--5.複製:
還可以繼續添加一個右鍵菜單,擴展成更多的保存方式.
void catcher_DoubleClick(object sender, EventArgs e)
{
Bitmap bmpCatched = new Bitmap(this.catcher.Width, this.catcher.Height);
Graphics g = Graphics.FromImage(bmpCatched);
g.CopyFromScreen(this.catcher.Location, new Point(0, 0), this.catcher.ClientRectangle.Size);
Clipboard.SetImage(bmpCatched);
if (MessageBox.Show("已經復制導剪切板") == DialogResult.OK)
{
Application.Exit();
}
}
2.製作一個可調整大小的半透明的無標題欄窗體.
在該窗體中應盡量實現應有的功能.
設置相關屬性:
this.Cursor = System.Windows.Forms.Cursors.SizeAll;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.ShowInTaskbar = false;
--1.繪製邊線及小方塊
//繪制矩形邊框與8個小方塊
private void FormCatcher_Paint(object sender, PaintEventArgs e)
{
using (Graphics g = e.Graphics)
{
Rectangle rect = new Rectangle(2, 2, this.ClientRectangle.Width-4, this.ClientRectangle.Height-4);
g.DrawRectangle(Pens.Red, rect);
//繪制小方塊,只要有邊線,不畫方塊,也可以調整大小
for (int i = 0; i <= 7; i++)
{
g.FillRectangle(Brushes.Red, this.GetBoundsOfSmallBlock(i));
}
}
}
--2.調整窗體大小及移動窗体
//注意:調得太快時,鼠標好像跑得太快,有點不同步的感覺.
private void FormCatcher_MouseMove(object sender, MouseEventArgs e)
{
int d = 10;
if (e.X < d)//左邊緣
{
if (e.Y < d)//左上
{
this.Cursor = Cursors.SizeNWSE;
if (this.isMouseLeftDown)
{
this.Location = new Point(Cursor.Position.X, Cursor.Position.Y);
this.Width = Math.Abs(Cursor.Position.X - this.bottomLoc.X);
this.Height = Math.Abs(Cursor.Position.Y - this.bottomLoc.Y);
}
}
else if (Math.Abs(e.Y - this.Height) < d)//左下
{
this.Cursor = Cursors.SizeNESW;
if (this.isMouseLeftDown)
{
this.Location = new Point(Cursor.Position.X,this.Location.Y);
this.Width = Math.Abs(Cursor.Position.X - this.bottomLoc.X);
this.Height = Math.Abs(Cursor.Position.Y - this.Location.Y);
}
}
else//左
{
this.Cursor = Cursors.SizeWE;
if (this.isMouseLeftDown)
{
this.Location = new Point(Cursor.Position.X, this.Location.Y);
this.Width = Math.Abs(Cursor.Position.X - this.bottomLoc.X);
}
}
}
else if (Math.Abs(e.X - this.Width) < d)//右邊緣
{
if (e.Y < d)//右上
{
this.Cursor = Cursors.SizeNESW;
if (this.isMouseLeftDown)
{
this.Location = new Point(this.Location.X, Cursor.Position.Y);
this.Width = Math.Abs(Cursor.Position.X - this.Location.X);
this.Height = Math.Abs(Cursor.Position.Y - this.bottomLoc.Y);
}
}
else if (Math.Abs(e.Y - this.Height) < d)//右下
{
this.Cursor = Cursors.SizeNWSE;
if (this.isMouseLeftDown)
{
this.Height = Cursor.Position.Y - this.Location.Y;
this.Width = Cursor.Position.X - this.Location.X;
}
}
else//右
{
this.Cursor = Cursors.SizeWE;
if (this.isMouseLeftDown)
{
this.Width = Cursor.Position.X - this.Location.X;
}
}
}
else
{
if (e.Y < d)//上邊緣
{
this.Cursor = Cursors.SizeNS;//中上
if (this.isMouseLeftDown)
{
this.Location = new Point(this.Location.X,Cursor.Position.Y);
this.Height = Math.Abs(Cursor.Position.Y - this.bottomLoc.Y);
}
}
else if (Math.Abs(e.Y - this.Height) < d)//下邊緣
{
this.Cursor = Cursors.SizeNS;//中下
if (this.isMouseLeftDown)
{
this.Height = Cursor.Position.Y - this.Location.Y;
}
}
else//非邊緣區域
{
this.Cursor = Cursors.SizeAll;
if (this.isMouseLeftDown)
{//按下鼠標左鍵並拖動窗口,改變窗口位置
this.Location = new Point(Cursor.Position.X - this.dxCursorToWindow,
Cursor.Position.Y - this.dyCursorToWindow);
}
}
}
}
3.附源碼
源碼1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
namespace QQCatchScreen
{
public partial class FormCatcher : Form
{
public FormCatcher()
{
InitializeComponent();
this.Paint += new System.Windows.Forms.PaintEventHandler(this.FormCatcher_Paint);
this.Resize += new EventHandler(FormCatcher_Resize);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FormCatcher_MouseUp);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FormCatcher_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FormCatcher_MouseMove);
}
private bool isMouseLeftDown = false;
/// <summary>
/// 鼠標按下時鼠標與窗體位置橫坐標差
/// </summary>
private int dxCursorToWindow = 0;
/// <summary>
/// 鼠標按下時鼠標與窗體位置縱坐標差
/// </summary>
private int dyCursorToWindow = 0;
/// <summary>
/// 窗體右下角的座標
/// </summary>
private Point bottomLoc = Point.Empty;
void FormCatcher_Resize(object sender, EventArgs e)
{
this.Refresh();
}
//繪制矩形邊框與8個小方塊
private void FormCatcher_Paint(object sender, PaintEventArgs e)
{
using (Graphics g = e.Graphics)
{
Rectangle rect = new Rectangle(2, 2, this.ClientRectangle.Width-4, this.ClientRectangle.Height-4);
g.DrawRectangle(Pens.Red, rect);
//繪制小方塊,只要有邊線,不畫方塊,也可以調整大小
for (int i = 0; i <= 7; i++)
{
g.FillRectangle(Brushes.Red, this.GetBoundsOfSmallBlock(i));
}
}
}
/// <summary>
/// 獲取指定序號的小方塊的位置
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
private Rectangle GetBoundsOfSmallBlock(int index)
{
int x = 0;
int y = 0;
int w = 4;
int h = 4;
switch (index)
{
case 0:
case 3:
case 5:
x = 0;
break;
case 1:
case 6:
x = this.ClientRectangle.Width / 2 -3;//
break;
case 2:
case 4:
case 7:
x = this.ClientRectangle.Width-4;//
break;
default:
throw new IndexOutOfRangeException("小方塊序號錯誤,應該在?0,?");
}
switch (index)
{
case 0:
case 1:
case 2:
y = 0;
break;
case 3:
case 4:
y = this.ClientRectangle.Height / 2 -3;//
break;
case 5:
case 6:
case 7:
y = this.ClientRectangle.Height-4;//
break;
default:
throw new IndexOutOfRangeException("小方塊序號錯誤,應該在?0,?");
}
return new Rectangle(x, y, w, h);
}
private void FormCatcher_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
this.isMouseLeftDown = true;
this.dxCursorToWindow = Cursor.Position.X - this.Location.X;
this.dyCursorToWindow = Cursor.Position.Y - this.Location.Y;
this.bottomLoc = new Point(this.Location.X + this.Width, this.Location.Y + this.Height);
}
}
private void FormCatcher_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
this.isMouseLeftDown = false;
this.dxCursorToWindow = this.dyCursorToWindow = 0;
this.bottomLoc = new Point(this.Location.X + this.Width, this.Location.Y + this.Height);
}
}
//調整大小就在這裡實現
//Bug:調得太快時,效果不好.
private void FormCatcher_MouseMove(object sender, MouseEventArgs e)
{
int d = 10;
if (e.X < d)//左邊緣
{
if (e.Y < d)//左上
{
this.Cursor = Cursors.SizeNWSE;
if (this.isMouseLeftDown)
{
this.Location = new Point(Cursor.Position.X, Cursor.Position.Y);
this.Width = Math.Abs(Cursor.Position.X - this.bottomLoc.X);
this.Height = Math.Abs(Cursor.Position.Y - this.bottomLoc.Y);
}
}
else if (Math.Abs(e.Y - this.Height) < d)//左下
{
this.Cursor = Cursors.SizeNESW;
if (this.isMouseLeftDown)
{
this.Location = new Point(Cursor.Position.X,this.Location.Y);
this.Width = Math.Abs(Cursor.Position.X - this.bottomLoc.X);
this.Height = Math.Abs(Cursor.Position.Y - this.Location.Y);
}
}
else//左
{
this.Cursor = Cursors.SizeWE;
if (this.isMouseLeftDown)
{
this.Location = new Point(Cursor.Position.X, this.Location.Y);
this.Width = Math.Abs(Cursor.Position.X - this.bottomLoc.X);
}
}
}
else if (Math.Abs(e.X - this.Width) < d)//右邊緣
{
if (e.Y < d)//右上
{
this.Cursor = Cursors.SizeNESW;
if (this.isMouseLeftDown)
{
this.Location = new Point(this.Location.X, Cursor.Position.Y);
this.Width = Math.Abs(Cursor.Position.X - this.Location.X);
this.Height = Math.Abs(Cursor.Position.Y - this.bottomLoc.Y);
}
}
else if (Math.Abs(e.Y - this.Height) < d)//右下
{
this.Cursor = Cursors.SizeNWSE;
if (this.isMouseLeftDown)
{
this.Height = Cursor.Position.Y - this.Location.Y;
this.Width = Cursor.Position.X - this.Location.X;
}
}
else//右
{
this.Cursor = Cursors.SizeWE;
if (this.isMouseLeftDown)
{
this.Width = Cursor.Position.X - this.Location.X;
}
}
}
else
{
if (e.Y < d)//上邊緣
{
this.Cursor = Cursors.SizeNS;//中上
if (this.isMouseLeftDown)
{
this.Location = new Point(this.Location.X,Cursor.Position.Y);
this.Height = Math.Abs(Cursor.Position.Y - this.bottomLoc.Y);
}
}
else if (Math.Abs(e.Y - this.Height) < d)//下邊緣
{
this.Cursor = Cursors.SizeNS;//中下
if (this.isMouseLeftDown)
{
this.Height = Cursor.Position.Y - this.Location.Y;
}
}
else//非邊緣區域
{
this.Cursor = Cursors.SizeAll;
if (this.isMouseLeftDown)
{//按下鼠標左鍵並拖動窗口,改變窗口位置
this.Location = new Point(Cursor.Position.X - this.dxCursorToWindow,
Cursor.Position.Y - this.dyCursorToWindow);
}
}
}
}
}
}
源碼2:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
namespace QQCatchScreen
{
public partial class FormBack : Form
{
/// <summary>
/// 保存整個屏幕的圖像
/// </summary>
private Bitmap screenImage = null;
/// <summary>
/// 用於確定最終捕獲圖像的窗口
/// </summary>
private FormCatcher catcher = new FormCatcher();
/// <summary>
/// 用於記錄catcher的位置
/// </summary>
private Point catcherLoc = Point.Empty;
/// <summary>
/// 標記鼠標左鍵是否按下
/// </summary>
private bool isMouseLeftDown = false;
public FormBack()
{
InitializeComponent();
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FormBack_MouseUp);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FormBack_MouseMove);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FormBack_MouseDown);
this.Load += new System.EventHandler(this.FormBack_Load);
}
private void FormBack_Load(object sender, EventArgs e)
{
this.Cursor = new Cursor("cur.cur");
//設置位置和背景
this.Bounds = Screen.PrimaryScreen.Bounds;
this.screenImage = this.GetScreenImage();
this.BackgroundImage = this.screenImage;
//加載捕獲窗口
this.catcher.Opacity = 0.4;
this.catcher.Visible = false;
this.catcher.MouseDown += new MouseEventHandler(catcher_MouseDown);
this.catcher.DoubleClick += new EventHandler(catcher_DoubleClick);
this.catcher.SizeChanged += new EventHandler(catcher_SizeChanged);
this.catcher.VisibleChanged += new EventHandler(catcher_VisibleChanged);
this.catcher.LocationChanged += new EventHandler(catcher_LocationChanged);
}
void catcher_VisibleChanged(object sender, EventArgs e)
{
if (!this.catcher.Visible)
{
this.label_CatcherWidth.Text = "寬度 ?0";
this.label_CatcherHeight.Text = "高度 ?0 ";
}
}
void catcher_LocationChanged(object sender, EventArgs e)
{
this.label_CatcherLoc.Text = "位置 X: " + this.catcher.Location.X + ", Y: " + this.catcher.Location.Y;
}
void catcher_SizeChanged(object sender, EventArgs e)
{
this.label_CatcherWidth.Text = "寬度 " + this.catcher.Width;
this.label_CatcherHeight.Text = "高度 " + this.catcher.Height;
}
void catcher_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
this.catcherLoc = Point.Empty;
this.isMouseLeftDown = false;
this.catcher.Visible = false;
}
}
void catcher_DoubleClick(object sender, EventArgs e)
{
Bitmap bmpCatched = new Bitmap(this.catcher.Width, this.catcher.Height);
Graphics g = Graphics.FromImage(bmpCatched);
g.CopyFromScreen(this.catcher.Location, new Point(0, 0), this.catcher.ClientRectangle.Size);
Clipboard.SetImage(bmpCatched);
if (MessageBox.Show("已經復制導剪切板") == DialogResult.OK)
{
Application.Exit();
}
}
/// <summary>
/// 獲取屏幕圖像
/// </summary>
private Bitmap GetScreenImage()
{
Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
Graphics g = Graphics.FromImage(bmp);
g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size);
g.Dispose();
return bmp;
}
private void FormBack_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
this.catcherLoc = Point.Empty;
this.isMouseLeftDown = false;
}
}
private void FormBack_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
if (!this.catcher.Visible)
{
Application.Exit();
}
else
{
this.catcher.Visible = false;
this.catcherLoc = Point.Empty;
this.isMouseLeftDown = false;
}
}
else if (e.Button == MouseButtons.Left)
{
if (!this.catcher.Visible)
{
this.catcherLoc = e.Location;
this.isMouseLeftDown = true;
}
}
}
private void FormBack_MouseMove(object sender, MouseEventArgs e)
{
if (!this.catcher.Visible)
{
this.label_CatcherLoc.Text = "位置 X: " + e.X + ", Y: " + e.Y;
}
if (this.isMouseLeftDown)
{
Rectangle rect = new Rectangle();
rect.X = e.X > this.catcherLoc.X ? this.catcherLoc.X : e.X;
rect.Y = e.Y > this.catcherLoc.Y ? this.catcherLoc.Y : e.Y;
rect.Width = Math.Abs(e.X - this.catcherLoc.X);
rect.Height = Math.Abs(e.Y - this.catcherLoc.Y);
this.catcher.Bounds = rect;
if (!this.catcher.Visible)
{
this.catcher.Show(this);
}
}
}
private void panel_Info_MouseEnter(object sender, EventArgs e)
{
Panel pl = (Panel)sender;
if (pl.Right < this.Width / 2)//在左邊
{
pl.Location = new Point(this.Width - pl.Width - 20, pl.Location.Y);
}
else
{
pl.Location = new Point(10, 10);
}
}
}
}