C# 实现屏幕截图

时间:2021-04-01 15:25:35

 

//创建用户控件

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CutDrawing
{
public partial class Catch : Form
{
public Catch()
{
InitializeComponent();
}
#region 用户变量
//记录鼠标按下坐标,确定绘图起点
private Point DownPoint = Point.Empty;
//截图完成
private bool CatchFinished = false;
//截图开始
private bool CatchStart = false;
//保存原始图像
private Bitmap originBmp;
//保存截图的矩形
private Rectangle CatchRect;
#endregion

private void Catch_Load(object sender, EventArgs e)
{
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
this.UpdateStyles();
//BackgroundImage为全屏图片,我们另用变量来保存全屏图片
originBmp = new Bitmap(this.BackgroundImage);
}

private void Catch_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
}

private void Catch_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
//如果捕捉没有开始
if (!CatchStart)
{
CatchStart = true;
//保存鼠标按下坐标
DownPoint = new Point(e.X, e.Y);
}
}
}

private void Catch_MouseMove(object sender, MouseEventArgs e)
{
//如果捕捉开始
if (CatchStart)
{
//新建一个图片对象,并让它与原始图片相同
Bitmap destBmp = (Bitmap)originBmp.Clone();
//获取鼠标的坐标
Point newPoint = new Point(DownPoint.X, DownPoint.Y);
//在刚才新建的图片上新建一个画板
Graphics g = Graphics.FromImage(destBmp);
//获取画笔对象
Pen pen = new Pen(Color.Blue, 1);
//获取矩形的长和宽
int width = Math.Abs(e.X - DownPoint.X);
int height = Math.Abs(e.Y - DownPoint.Y);
//判断矩形的起始坐标
if (e.X < DownPoint.X)
newPoint.X = e.X;
if (e.Y < DownPoint.Y)
newPoint.Y = e.Y;
//保存矩形
CatchRect = new Rectangle(newPoint, new Size(width, height));
//将矩形花在这个画板上
g.DrawRectangle(pen, CatchRect);
//释放这个画板
g.Dispose();
//重新创建一个Graphics类
Graphics g1 = this.CreateGraphics();
//如果之前那个画板不释放,而直接g=this.CreateGraphics()这样的话无法释放掉第一次创建的g,因为只是把地址转到新的g了,如同string一样。
//将刚才所画的图片画到这个窗体上
g1.DrawImage(destBmp, new Point(0, 0));
//这个也可以属于二次缓冲技术,如果直接将矩形画在窗体上,会造成图片抖动并且会有无数个矩形
//释放这个画板
g1.Dispose();
//释放掉Bmp对象。
destBmp.Dispose();
//要及时释放不会再次使用的对象,不然内存将会被大量消耗
}
}

private void Catch_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
//如果已经开始绘制
if (CatchStart)
{
//将开始绘制设为false
CatchStart = false;
//完成绘制设为true
CatchFinished = true;
}
}
}

private void Catch_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && CatchFinished)
{
if (CatchRect.Contains(new Point(e.X, e.Y)))
{
//新建一个与矩形等大的空白图片
Bitmap catchedBmp = new Bitmap(CatchRect.Width, CatchRect.Height);
//在空白图片上新建一个画板
Graphics g = Graphics.FromImage(catchedBmp);
//将origin中的指定部分按照指定大小画在画板上
g.DrawImage(originBmp, new Rectangle(0, 0, CatchRect.Width, CatchRect.Height), CatchRect, GraphicsUnit.Pixel);
//将图片保存到剪贴板上
Clipboard.SetImage(catchedBmp);
//释放Graphics对象
g.Dispose();
//完成一次操作
CatchFinished = false;
//将背景图片设置为originBmp中的图片
this.BackgroundImage = originBmp;
//释放新图片对象
catchedBmp.Dispose();
this.DialogResult = DialogResult.OK;
this.Close();
}
}
}
}
}

//主窗体截图按钮方法

private void btnCatch_Click(object sender, EventArgs e)
{
//隐藏当前窗体
this.Hide();
//让线程睡眠一段时间,窗体消失需要一点时间
Thread.Sleep(50);
Catch catchForm = new Catch();
//新建一个和屏幕大小相同的图片
Bitmap CatchBmp = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);
//在新图片上创建一个画布
Graphics g = Graphics.FromImage(CatchBmp);
//保存全屏图片
g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height));
//将Catch窗体的背景设为全屏时的图片
catchForm.BackgroundImage = CatchBmp;

if (catchForm.ShowDialog() == DialogResult.OK)
{
//如果Catch窗体结束,就将剪贴板中的图片放到信息发送框中
IDataObject iData = Clipboard.GetDataObject();
DataFormats.Format myFormat = DataFormats.GetFormat(DataFormats.Bitmap);
if (iData.GetDataPresent(DataFormats.Bitmap))
{
rtxtMessage.Paste(myFormat);
//清楚剪切板中的对象
Clipboard.Clear();
}
//再次显示此窗体
this.Show();
}
}