C#实现截图工具小项目
本文实例为大家分享了C#实现截图工具小项目的具体代码,供大家参考,具体内容如下
1.起因
一直用的截图是qq的截图,所以想要实现一个简单点的截图,为了方便。
2.思路
讲一下实现流程。
1、主窗体,上有截图按钮,点击进入截图窗体
2、在截图窗体中,背景设置为全屏幕的截图图片,无边框,窗体最大化,这时你看到的就是一张屏幕图,其实是一个窗体,然后我们将在这个窗体中截取图片,其实主要就是画板Graphics的使用,截取完之后图片将保存到剪切板。
3.代码
热键注册类HotKey.cs
using System; using System.Runtime.InteropServices; using System.Windows.Forms; namespace test {/// /// 热键类/// public class HotKey {/// /// 如果函数执行成功,返回值不为0,如果执行失败,返回值为0/// ///[DllImport("user32.dll", SetLastError = true)]public static extern bool RegisterHotKey(IntPtr hWnd,// 窗口的句柄, 当热键按下时,会产生WM_HOTKEY信息,该信息该会发送该窗口句柄int id,// 定义热键ID,属于唯一标识热键的作用uint fsModifiers,// 热键只有在按下Alt、 Ctrl、Shift、Windows等键时才会生效,即才会产生WM_HOTKEY信息Keys vk// 虚拟键,即按了Alt+Ctrl+ X ,X就是代表虚拟键); [DllImport("user32.dll", SetLastError = true)]public static extern bool UnregisterHotKey(IntPtr hWnd,// 窗口句柄int id// 要取消热键的ID); }}
主窗体Form1.cs
using System; using System.Drawing; using System.Drawing.Imaging; using System.Threading; using System.Timers; using System.Windows.Forms; namespace test {public partial class Form1 : Form { [Flags]public enum KeyModifiers { //定义热键值字符串(热键值是系统规定的,不能改变)None = 0,Alt = 1,Ctrl = 2,Shift = 4,WindowsKey = 8} public Form1() {InitializeComponent(); } //窗体加载时-注册快捷键private void Form1_Load(object sender, EventArgs e) {uint ctrlHotKey = (uint)(KeyModifiers.Alt | KeyModifiers.Ctrl); // 注册热键为Alt+Ctrl+A, "100"为唯一标识热键HotKey.RegisterHotKey(Handle,100,ctrlHotKey,Keys.A); } //截图按钮private void button1_Click(object sender, EventArgs e) {if (this.WindowState != FormWindowState.Minimized) {this.WindowState = FormWindowState.Minimized; Thread.Sleep(200); }int swidth = Screen.PrimaryScreen.Bounds.Width; int sheight = Screen.PrimaryScreen.Bounds.Height; Bitmap btm = new Bitmap(swidth,sheight); //空图与屏幕同大小Graphics g = Graphics.FromImage(btm); //空图的画板g.CopyFromScreen(new Point(0,0),new Point(0,0),new Size(swidth,sheight)); //将屏幕内容复制到空图Cutter cutter = new Cutter(btm); //传送截图cutter.FormBorderStyle = FormBorderStyle.None; //截图全屏,无边框cutter.BackgroundImage = btm; //新的窗体截图做背景cutter.Show(); }private void tiaoZ(object sender, ElapsedEventArgs e) {} //窗体关闭-取消热键private void Form1_FormClosing(object sender, FormClosingEventArgs e) {HotKey.UnregisterHotKey(Handle,100); } //快捷键按下执行的事件private void GlobalKeyProcess() {this.WindowState = FormWindowState.Minimized; Thread.Sleep(200); button1.PerformClick(); } //重写。监视系统消息,调用对应方法protected override void WndProc(ref Message m) {const int WM_HOTKEY = 0x0312; //如果m.Msg的值为0x0312(我也不知道为什么是0x0312)那么表示用户按下了热键switch (m.Msg) {case WM_HOTKEY:if (m.WParam.ToString().Equals("100")) {GlobalKeyProcess(); }//todo其它热键break; }// 将系统消息传递自父类的WndProcbase.WndProc(ref m); }}}
截图窗体-核心 Cutter.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace test {public partial class Cutter : Form {Bitmap screenBtmp = null; //电脑屏幕的截图 public Cutter(Bitmap btm) {InitializeComponent(); screenBtmp = btm; } //鼠标右键退出private void Cutter_MouseClick(object sender, MouseEventArgs e) {if (e.Button == MouseButtons.Right) {this.DialogResult = DialogResult.OK; this.Close(); }} bool CatchStart = false; //自由截图开始Point downPoint; //初始点//鼠标左键按下-开始自由截图private void Cutter_MouseDown(object sender, MouseEventArgs e) {if (e.Button == MouseButtons.Left) {if (!CatchStart) {CatchStart = true; downPoint = new Point(e.X,e.Y); //初始点}}} Rectangle catchRec; //存放截取范围//鼠标移动-绘制自由截图路径private void Cutter_MouseMove(object sender, MouseEventArgs e) { //路径绘制,核心if (CatchStart) {////二次缓冲//不是直接在控件的背景画板上进行绘制鼠标移动路径,那样会造成绘制很多路径,因为前面绘制的路径还在//而是在内存中每移动一次鼠标就创建一张和屏幕截图一样的新BImtap,在这个Bitmap中绘制鼠标移动路径//然后在窗体背景画板上,绘制这个新的Bitmap,这样就不会造成绘制很多路径,因为每次都绘制了全新的Bitmao//但是这样做的话,因为鼠标移动的次数是大量的,所以在内存中会创建大量的Bitmap会造成内存消耗严重,所以每次移动绘制完后,//需要释放Dispose() 画板,画笔,Bitmap资源。//Bitmap copyBtmp = (Bitmap)screenBtmp.Clone(); //创建新的,在其上绘制路径//左上角Point firstP = new Point(downPoint.X,downPoint.Y); //新建画板,画笔Graphics g = Graphics.FromImage(copyBtmp); Pen p = new Pen(Color.Red,1); //计算路径范围int width = Math.Abs(e.X - downPoint.X); int height = Math.Abs(e.Y - downPoint.Y); if (e.X < downPoint.X) {firstP.X = e.X; }if (e.Y < downPoint.Y) {firstP.Y = e.Y; }//绘制路径catchRec = new Rectangle(firstP,new Size(width,height)); //将路径绘制在新的BItmap上,之后要释放g.DrawRectangle(p, catchRec); g.Dispose(); p.Dispose(); //窗体背景画板Graphics gf = this.CreateGraphics(); //将新图绘制在窗体的画板上--自由截图-路径绘制处,其实还是一张和屏幕同样大小的图片,只不过上面有红色的选择路径gf.DrawImage(copyBtmp,new Point(0,0)); gf.Dispose(); //释放内存BimtapcopyBtmp.Dispose(); }} bool catchFinished = false; //自由截图结束标志//鼠标左键弹起-结束自由截图private void Cutter_MouseUp(object sender, MouseEventArgs e) {if (e.Button == MouseButtons.Left) {if (CatchStart) {CatchStart = false; catchFinished = true; }}} //鼠标左键双击,保存自由截取的图片private void Cutter_MouseDoubleClick(object sender, MouseEventArgs e) {if((e.Button == MouseButtons.Left) && catchFinished){//创建用户截取的范围大小的空图Bitmap catchBtmp = new Bitmap(catchRec.Width,catchRec.Height); Graphics g = Graphics.FromImage(catchBtmp); //在原始的屏幕截图ScreenBitmap上 截取 用户选择范围大小的区域绘制到上面的空图//绘制完后,这个空图就是我们想要的截取的图片//参数1原图//参数2在空图上绘制的范围区域//参数3原图的截取范围//参数4度量单位g.DrawImage(screenBtmp,new Rectangle(0,0,catchRec.Width,catchRec.Height),catchRec,GraphicsUnit.Pixel); //将自由截取的图片保存到剪切板中Clipboard.Clear(); Clipboard.SetImage(catchBtmp); g.Dispose(); catchFinished = false; this.BackgroundImage = screenBtmp; catchBtmp.Dispose(); this.DialogResult = DialogResult.OK; this.Close(); }}}}
【C#实现截图工具小项目】以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
推荐阅读
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 标签、语法规范、内联框架、超链接、CSS的编写位置、CSS语法、开发工具、块和内联、常用选择器、后代元素选择器、伪类、伪元素。
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- java中如何实现重建二叉树
- 最有效的时间管理工具(赢效率手册和总结笔记)
- 人脸识别|【人脸识别系列】| 实现自动化妆