C#實(shí)現(xiàn)截圖工具小項(xiàng)目
本文實(shí)例為大家分享了C#實(shí)現(xiàn)截圖工具小項(xiàng)目的具體代碼,供大家參考,具體內(nèi)容如下
1.起因
一直用的截圖是qq的截圖,所以想要實(shí)現(xiàn)一個(gè)簡單點(diǎn)的截圖,為了方便。
2.思路
講一下實(shí)現(xiàn)流程。
1、主窗體,上有截圖按鈕,點(diǎn)擊進(jìn)入截圖窗體
2、在截圖窗體中,背景設(shè)置為全屏幕的截圖圖片,無邊框,窗體最大化,這時(shí)你看到的就是一張屏幕圖,其實(shí)是一個(gè)窗體,然后我們將在這個(gè)窗體中截取圖片,其實(shí)主要就是畫板Graphics的使用,截取完之后圖片將保存到剪切板。
3.代碼
熱鍵注冊類 HotKey.cs
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace test {
/// <summary>
/// 熱鍵類
/// </summary>
public class HotKey {
/// <summary>
/// 如果函數(shù)執(zhí)行成功,返回值不為0,如果執(zhí)行失敗,返回值為0
/// </summary>
/// <returns></returns>
[DllImport("user32.dll", SetLastError = true)]
public static extern bool RegisterHotKey(
IntPtr hWnd, // 窗口的句柄, 當(dāng)熱鍵按下時(shí),會產(chǎn)生WM_HOTKEY信息,該信息該會發(fā)送該窗口句柄
int id, // 定義熱鍵ID,屬于唯一標(biāo)識熱鍵的作用
uint fsModifiers, // 熱鍵只有在按下Alt、 Ctrl、Shift、Windows等鍵時(shí)才會生效,即才會產(chǎn)生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 { //定義熱鍵值字符串(熱鍵值是系統(tǒng)規(guī)定的,不能改變)
None = 0,
Alt = 1,
Ctrl = 2,
Shift = 4,
WindowsKey = 8
}
public Form1() {
InitializeComponent();
}
//窗體加載時(shí)-注冊快捷鍵
private void Form1_Load(object sender, EventArgs e) {
uint ctrlHotKey = (uint)(KeyModifiers.Alt | KeyModifiers.Ctrl);
// 注冊熱鍵為Alt+Ctrl+A, "100"為唯一標(biāo)識熱鍵
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)); //將屏幕內(nèi)容復(fù)制到空圖
Cutter cutter = new Cutter(btm); //傳送截圖
cutter.FormBorderStyle = FormBorderStyle.None; //截圖全屏,無邊框
cutter.BackgroundImage = btm; //新的窗體截圖做背景
cutter.Show();
}
private void tiaoZ(object sender, ElapsedEventArgs e) {
}
//窗體關(guān)閉-取消熱鍵
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
HotKey.UnregisterHotKey(Handle,100);
}
//快捷鍵按下執(zhí)行的事件
private void GlobalKeyProcess() {
this.WindowState = FormWindowState.Minimized;
Thread.Sleep(200);
button1.PerformClick();
}
//重寫。監(jiān)視系統(tǒng)消息,調(diào)用對應(yīng)方法
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;
}
// 將系統(tǒng)消息傳遞自父類的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;
}
//鼠標(biāo)右鍵退出
private void Cutter_MouseClick(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Right) {
this.DialogResult = DialogResult.OK;
this.Close();
}
}
bool CatchStart = false; //自由截圖開始
Point downPoint; //初始點(diǎn)
//鼠標(biāo)左鍵按下-開始自由截圖
private void Cutter_MouseDown(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
if (!CatchStart) {
CatchStart = true;
downPoint = new Point(e.X,e.Y); //初始點(diǎn)
}
}
}
Rectangle catchRec;//存放截取范圍
//鼠標(biāo)移動(dòng)-繪制自由截圖路徑
private void Cutter_MouseMove(object sender, MouseEventArgs e) { //路徑繪制,核心
if (CatchStart) {
//
//二次緩沖
//不是直接在控件的背景畫板上進(jìn)行繪制鼠標(biāo)移動(dòng)路徑,那樣會造成繪制很多路徑,因?yàn)榍懊胬L制的路徑還在
//而是在內(nèi)存中每移動(dòng)一次鼠標(biāo)就創(chuàng)建一張和屏幕截圖一樣的新BImtap,在這個(gè)Bitmap中繪制鼠標(biāo)移動(dòng)路徑
//然后在窗體背景畫板上,繪制這個(gè)新的Bitmap,這樣就不會造成繪制很多路徑,因?yàn)槊看味祭L制了全新的Bitmao
//但是這樣做的話,因?yàn)槭髽?biāo)移動(dòng)的次數(shù)是大量的,所以在內(nèi)存中會創(chuàng)建大量的Bitmap會造成內(nèi)存消耗嚴(yán)重,所以每次移動(dòng)繪制完后,
//需要釋放Dispose() 畫板,畫筆,Bitmap資源。
//
Bitmap copyBtmp = (Bitmap)screenBtmp.Clone(); //創(chuàng)建新的,在其上繪制路徑
//左上角
Point firstP = new Point(downPoint.X,downPoint.Y);
//新建畫板,畫筆
Graphics g = Graphics.FromImage(copyBtmp);
Pen p = new Pen(Color.Red,1);
//計(jì)算路徑范圍
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();
//將新圖繪制在窗體的畫板上 -- 自由截圖-路徑繪制處,其實(shí)還是一張和屏幕同樣大小的圖片,只不過上面有紅色的選擇路徑
gf.DrawImage(copyBtmp,new Point(0,0));
gf.Dispose();
//釋放內(nèi)存Bimtap
copyBtmp.Dispose();
}
}
bool catchFinished = false; //自由截圖結(jié)束標(biāo)志
//鼠標(biāo)左鍵彈起-結(jié)束自由截圖
private void Cutter_MouseUp(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
if (CatchStart) {
CatchStart = false;
catchFinished = true;
}
}
}
//鼠標(biāo)左鍵雙擊,保存自由截取的圖片
private void Cutter_MouseDoubleClick(object sender, MouseEventArgs e) {
if((e.Button == MouseButtons.Left) && catchFinished){
//創(chuàng)建用戶截取的范圍大小的空圖
Bitmap catchBtmp = new Bitmap(catchRec.Width,catchRec.Height);
Graphics g = Graphics.FromImage(catchBtmp);
//在原始的屏幕截圖ScreenBitmap上 截取 用戶選擇范圍大小的區(qū)域 繪制到上面的空圖
//繪制完后,這個(gè)空圖就是我們想要的截取的圖片
//參數(shù)1 原圖
//參數(shù)2 在空圖上繪制的范圍區(qū)域
//參數(shù)3 原圖的截取范圍
//參數(shù)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();
}
}
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#實(shí)現(xiàn)漢字轉(zhuǎn)拼音(多音字)功能詳解
這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)漢字轉(zhuǎn)拼音(支持多音字)的功能,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下2023-02-02
Unity3D動(dòng)態(tài)生成平面網(wǎng)格
這篇文章主要為大家詳細(xì)介紹了Unity3D動(dòng)態(tài)生成平面網(wǎng)格,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02
關(guān)于C# Math 處理奇進(jìn)偶不進(jìn)的實(shí)現(xiàn)代碼
下面小編就為大家?guī)硪黄P(guān)于C# Math 處理奇進(jìn)偶不進(jìn)的實(shí)現(xiàn)代碼。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-05-05

