这里截图针对的并非动态截图,只能截取静态图片。全部采用C#语法,并不涉及API的调用。
原理:当触发截图操作时,首先新建一个Form,让当前桌面作为Form的背景图片,并设置窗体为顶层,并最大化显示,
其次,当用户单击鼠标按下并移动时动态画矩形。当用户释放鼠标并双击界面时,截取指定区域图片。
步骤:
首先获取桌面图片:
Screen screen = Screen.PrimaryScreen;//得到显示设备
Rectangle displayRect = screen.Bounds;//获取显示设备的大小
Bitmap bitmap = new Bitmap(displayRect.Width, displayRect.Height);//新建一个显示设备大小的图片作为画布
Graphics g = Graphics.FromImage(bitmap);//利用新建的图像创建画板
g.CopyFromScreen(new Point(0, 0), new Point(0, 0), bitmap.Size);//将屏幕复制到画板上,实际上是复制到了bitmap画布上
其次设置Form必要属性:
this.DoubleBuffered = true;//开启控件双缓冲
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
this.UpdateStyles();//将窗体设置为双重缓存,有效降低闪烁。
以下属性设置,将使窗体最大化并遮住整个屏幕包括任务栏:
this.TopMost = true;//设置为顶层窗体
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;//无边框
this.WindowState = FormWindowState.Maximized;//最大化
双缓冲技术:
//注:双缓冲技术--可避免界面闪烁
//首先将要画的东西,画在缓冲区的设备上,然后再画在实际的设备上,如上操作。另外需注意释放缓冲区不再要的资源
//启用窗体的双缓冲,代码如下:
//this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
//this.UpdateStyles();//将窗体设置为双重缓存,有效降低闪烁。
//启用控件的双缓冲,代码如下:
//this.DoubleBuffered = true;
//图片裁剪,可以考虑使用:Bitmap.Clone()方法,该方法带裁剪矩形大小参数等。
//另外,Graphics是由哪个对象创建而来,则Graphics的操作最终都是在创建的哪个对象上操作的。
//如:Bitmap bitmap = new Bitmap();Graphics g = Graphics.FromImage(bitmap);g.DrawLine()
//这里画的线,实际上将画在图片上即bitmap对象上。此时bitmap图像将有一根画好的线条。
关键代码:
private void btnScreen_Click(object sender, EventArgs e)
{
Screen screen = Screen.PrimaryScreen;//得到显示设备
Rectangle displayRect = screen.Bounds;//获取显示设备的大小
Bitmap bitmap = new Bitmap(displayRect.Width, displayRect.Height);//新建一个显示设备大小的图片作为画布
Graphics g = Graphics.FromImage(bitmap);//利用新建的图像创建画板
g.CopyFromScreen(new Point(0, 0), new Point(0, 0), bitmap.Size);//将屏幕复制到画板上,实际上是复制到了bitmap画布上
Form2 frm = new Form2();
frm.BackgroundImage = bitmap;
frm.Show();
g.Dispose();
}
//Form2关键代码
private Point statrPoint;
private bool isDown = false;
private bool isDoubleDown = false;
private Rectangle saveRect;
private void Form2_MouseDown(object sender, MouseEventArgs e)
{
if (this.isDoubleDown)
return;
this.isDown = true;
this.statrPoint = e.Location;
}
private void Form2_MouseMove(object sender, MouseEventArgs e)
{
if (!this.isDown || this.isDoubleDown)
return;
Bitmap cacheBmp = (Bitmap)this.BackgroundImage.Clone();//克隆背景图片作为画板的画布
Graphics g = Graphics.FromImage(cacheBmp);//新建画板
//画矩形到画板,实际画在cacheBmp上
g.DrawRectangle(Pens.Red, this.statrPoint.X, this.statrPoint.Y, e.X - this.statrPoint.X, e.Y - this.statrPoint.Y);
g.Dispose();//释放画板资源
g = this.CreateGraphics();
g.DrawImage(cacheBmp, 0, 0);//将缓冲区cacheBmp图像画在窗体上
cacheBmp.Dispose();//释放缓冲区图像
this.saveRect = new Rectangle(this.statrPoint.X, this.statrPoint.Y, e.X - this.statrPoint.X, e.Y - this.statrPoint.Y);
}
private void Form2_MouseUp(object sender, MouseEventArgs e)
{
this.isDown = false;
if (!this.isDoubleDown)
return;
//裁剪图片的方法Clone()
try
{
Bitmap savePic = ((Bitmap)this.BackgroundImage).Clone(saveRect, this.BackgroundImage.PixelFormat);
savePic.Save(@"C:\Users\Administrator\Desktop\screen.jpg");
savePic.Dispose();//释放资源
}
catch (Exception ex)
{
Console.WriteLine("错误::"+ex.Message);
}
finally {
this.isDoubleDown = false;
this.Close();
}
}
private void Form2_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.isDoubleDown = true;
}
private void Form2_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape) {
this.Close();
}
}
}
//注:该操作还存在矩形判断问题,但不影响截图操作(从左上到右下画矩形操作)
效果图如下: