C#实现截图工具小项目

本文实例为大家分享了C#实现截图工具小项目的具体代码,供大家参考,具体内容如下

1.起因

一直用的截图是qq的截图,所以想要实现一个简单点的截图,为了方便。

2.思路

讲一下实现流程。

1、主窗体,上有截图按钮,点击进入截图窗体
2、在截图窗体中,背景设置为全屏幕的截图图片,无边框,窗体最大化,这时你看到的就是一张屏幕图,其实是一个窗体,然后我们将在这个窗体中截取图片,其实主要就是画板Graphics的使用,截取完之后图片将保存到剪切板。

3.代码

热键注册类   HotKey.cs

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace test {
    /// <summary>
    /// 热键类
    /// </summary>
    public class HotKey {
        /// <summary>
        /// 如果函数执行成功,返回值不为0,如果执行失败,返回值为0
        /// </summary>
        /// <returns></returns>
        [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;
            }
            // 将系统消息传递自父类的WndProc
            base.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();
                //释放内存Bimtap
                copyBtmp.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();
            }
        }
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#之set与get方法的用法案例

    需求:学生输入姓名和语文.数学.英语,编程求出总分和平均分,并在屏幕上显示XX的总分和平均分 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; //学生输入姓名和语文.数学.英语,编程求出总分和平均分,并在屏幕上显示XX的总分和平均分 namespace Student_management_system { cla

  • C#实现电脑麦克风录音

    本实例通过Naudio库完成麦克风录音并把PCM脉冲信号保存成wav音频文件.关于音频的采样率.比特率.声道等问题请查阅相关资料,本示例不做解释.Naudio库 请从NuGet搜索并下载. 录音接口类: public interface ISpeechRecorder { void SetFileName(string fileName); void StartRec(); void StopRec(); } 录音实现类: using System; using NAudio.Wave; nam

  • C# windows语音识别与朗读实例

    C# windows语音识别与朗读示例,供大家参考,具体内容如下 本示例通过windows语音识别功能进行语音识别和文本朗读. 打开windows麦克风,点击start按键,大声朗读 "中国"."美国"."英国",识别成功将发出"嘟"的提示音并朗读对应结果. 用到的语音识别模块包括: using System.Speech.Recognition; using System.Speech.Synthesis; 动态连接库文件在

  • C#实现滑动开关效果

    C#重绘checkbox生成滑动开关,供大家参考,具体内容如下 通过调用checkbox控件的paint事件,在重绘事件里判断checked属性,如果选中绘制选中图形,如果未选中绘制未选中图形. 效果图: 绘制圆角矩形方法: /// <summary> /// 填充圆角矩形 /// </summary> /// <param name="g"></param> /// <param name="brush">

  • C#调用带结构体指针Dll的方法

    在C#中调用C(C++)类的DLL的时候,有时候C的接口函数包含很多参数,而且有的时候这些参数有可能是个结构体,而且有可能是结构体指针,那么在C#到底该如何安全的调用这样的DLL接口函数呢?本文将详细介绍如何调用各种参数的方法. 一.调用接口仅含普通变量 int fnAdd(int num1,int num2); 那么在C#调用这种函数最简单了,直接用函数原型即可,如下: [DllImport("你的dll名称", EntryPoint = "fnAdd", Cal

  • C# DirectShow预览摄像头并截图

    C# DirectShow预览摄像头并截图,供大家参考,具体内容如下 本事例通过Windows DirectX Filtergraph 一些列管道将电脑所接入视频采集设备的视频流播放到制定区域,通过ISampleGrabberCB接口的BufferCB回调函数截取图片. 用此方法预览图像cpu占用率极低,比其其他事件绑定并逐帧显示图像性能更佳. UI布局: 代码如下: using System; using System.Drawing; using System.Windows.Forms;

  • C# WebApi+Webrtc局域网音视频通话实例

    C# WebApi+Webrtc 局域网音视频通话示例,供大家参考,具体内容如下 本示例通过IIS部署webapi,利用websocket进行webrtc消息交换,通过Chrome浏览器访问,可实现局域网内webrtc 音视频通话. 通过Chrome浏览器打开localhost/live.html本地网址,打开两个本地网,点击任意页面连接按钮即联通. 本示例未实现NAT穿透处理,互联网无法联通,如需NAT穿透请自行查阅相关资料. 关于webrtc.webapi相关技术说明请自行查阅相关资料,本文

  • C#实现截图工具小项目

    本文实例为大家分享了C#实现截图工具小项目的具体代码,供大家参考,具体内容如下 1.起因 一直用的截图是qq的截图,所以想要实现一个简单点的截图,为了方便. 2.思路 讲一下实现流程. 1.主窗体,上有截图按钮,点击进入截图窗体 2.在截图窗体中,背景设置为全屏幕的截图图片,无边框,窗体最大化,这时你看到的就是一张屏幕图,其实是一个窗体,然后我们将在这个窗体中截取图片,其实主要就是画板Graphics的使用,截取完之后图片将保存到剪切板. 3.代码 热键注册类   HotKey.cs using

  • 微信小程序实战之运维小项目

    前言 自从微信推出小程序以来,现在业界炒的非常的火,具说叫微信小程序是因为某公司不让叫应用号,我在朋友圈也看过pony的和张小龙朋友圈关于名字的讨论截图,不知道是真是假,反正名字是定了,叫啥无所谓,还是知道它是干啥的比较重要, 像网上说什么新风口了,原生APP以后没活路了等相关文章喜欢的可以多看看, 我们今天不会在产品层面上去介绍小程序,因为我们是搞运维的,所以我还是在运维层面怎么使用小程序. 今天我们用实际例子来讲解和普及小小程序如何使用,来实现类似IP138的功能,输入IP可以查看IP的详细

  • C#实现属于自己的QQ截图工具

    下面就具体介绍下实现截图工具的实现思路. 为了让大家更清楚地知道如何去实现自己的截图工具,首先我来描述下截图的一个过程--我们使用QQ的截图工具和Windows 自带的截图工具都可以发现,当我们点击QQ窗体中的截图按钮时,此时我们将看到一个全屏图片,然后我们可以在其上截图,当鼠标左键按下时,即代表开始截图,并我们可以移动鼠标来改变截图的大小,鼠标弹起时即代表结束截图,此时我们可以双击矩形区域完全截图,并且可以通过粘贴操作把截取的图片粘贴到聊天窗口的发送区,鼠标右键点击则是退出截图.这样我们截图的

  • C语言学生信息管理系统小项目

    本文为大家分享了C语言学生信息管理系统小项目,供大家参考,具体内容如下 /* 运行环境:我是在linux里面用gcc编译的,在windows里应该也能运行,用的一些文件库函数都是c标准库,没有用linux的系统调用(纠正一下:system("clear")这个系统调用是linux的,windows里面用system("cls") ) (1)问题描述 学生信息包括:学号,姓名,年龄,性别,出生年月,地址,电话,E-mail等.试设计一学生信息管理系统,使之能提供以下功

  • Ubuntu 18.04中截图工具shutter的编辑按钮不可用的解决办法

    Shutter是一个由第三方提供的在Ubuntu上运行的截图工具,相对于系统自带的截图工具(默认可通过Ctrl + Shift + Print快捷键启动截图),最大的优点就是可以即时对图片进行编辑,在图片上做一些标记和文字标注等,使用起来很方便.在Ubuntu 16.04上,该软件运行一切正常,当将操作系统升级到18.04之后,启动Shutter后你会发现原先的编辑按钮不可用了.点击编辑按钮,提示说缺少libgoo-canvas-perl库.看来我们不得不手动将该软件所依赖的库装一遍了. 按照以

  • C语言实现密码本小项目

    一.引言 学C语言有一段时间了,趁着正好做了密码本的小项目,把它分享出来. 二.思路与原理 密码本,见名知意,就是存放账号密码,起到备忘录作用的本子,将需要备忘的数据通过加密存放在文本文件中,打开的文本文件为加密文本,需要通过软件查看已经存放的数据,提高安全性.(软件设计了启动密码,三次过后自动退出) 项目目标: 保存账号密码,退出后打开软件数据不丢失 进行简单加密 能按条件查找账号密码 能修改账号密码数据 能按条件进行删除数据 知识涉及到数组.文件操作的使用以及简单异或加密. 软件的部分截图如

  • Java小项目之迷宫游戏的实现方法

    项目要求: 一个网格迷宫由n行n列的单元格组成,每个大院个要么是空地(用0表示),要么是障碍物(用1表示),你的任务是找一条从起点到终点的移动序列,其中只能上下左右移动到相邻单元格.任何时候都不能在有障碍物的单元格中,也不能走到迷宫之外,起点为左上角和终点右下角. 项目功能: 解决迷宫路径查找问题,寻找一条从左上角迷宫入口到右下角迷宫出口的一条有效路径,0代表可走,1代表能走,找到请输出最终的迷宫和路径信息,找不到请输出不存在有效路径. 思路: 1.定义一个迷宫节点类型(MazeNode)的二维

  • vs2019 MFC实现office界面的画图小项目

    vs2019安装MFC 有许多新手不知道MFC在vs2019里的安装选项,其实它不会在勾选工作负载时自动默认勾选,而通常需要人为勾选,具体安装步骤如下:(安装时间不是很长,网速够快几分钟就下载完毕) 1.打开vs安装程序 2.选择Visual Studio扩展开发 3.选择C++ MFC 生成工具(x86 和 x64)进行安装 4.选择修改,等待安装 5.等待安装完成 6.安装完成,我们打开vs2019 7.我们创建新项目,可以看到已经有MFC应用这个选项 说明我们的MFC安装成功~ vs201

  • Python PyQt5干货满满小项目轻松实现高效抠图去背景

    目录 简介 1.获取API 2.API使用方法 3.可视化桌面制作 4.逻辑实现 5.美化 6.信号与槽绑定 7.全部代码 8.界面展示 简介 结合学习的PyQt5,弄点小项目,做次记录. 此项目是使用了removebg的API,进行实现抠图功能,将人物的背景扣去.将次功能封装到桌面上. 1.获取API 先打开removebg的网站 点击上面的工具和API 再点击API Docs 最后点击Get API Key,当然要先登录 2.API使用方法 在API Docs 下面有使用方法 3.可视化桌面

  • 利用Python实现一个简易的截图工具

    这是工作期间同事想要个截完图之后可以显示并且永远前置的截图小工具(即不会被其他程序覆盖)直接上代码: # # -*- coding: utf-8 -*- import tkinter as tk import pyautogui import tkinter from PIL import ImageTk from PIL import Image root = tk.Tk() root.wm_attributes('-topmost', 1) root.overrideredirect(Tru

随机推荐