C#軟體開發例項.私人訂製自己的螢幕截圖工具(四)基本截圖功能實現
實現原理
基本截圖的功能主要靠響應主窗體的滑鼠按下、滑鼠移動、滑鼠抬起幾個事件的功能來實現的。擷取的圖片區域使用“Label”元件來顯示,需要重新實現“Label”元件的“Paint”方法。
左鍵單擊開始截圖,右鍵單擊取消截圖,雙擊滑鼠左鍵完成截圖,將擷取的圖片儲存到Windows剪貼簿中。
新增“Label”元件
工具箱》公共元件》雙擊“Label”元件,修改元件屬性:
Name=lbl_CutImage,
AutoSize=False,
BackColor=Transparent,
Text = “”
“Form1_Load”事件新增程式碼:
this.lbl_CutImage.Hide();
定義截圖功能依賴的基本變數
#region 截圖基本變數
/// <summary>
/// 用於判斷是否已經開始截圖,控制資訊框是否顯示。
/// </summary>
private bool isCuting;
/// <summary>
/// 滑鼠按下的點
/// </summary>
private Point beginPoint;
/// <summary>
/// 最終確定的繪圖基點
/// </summary>
private Point endPoint;
/// <summary>
/// 用於記錄截圖顯示區域的大小(包括調整塊的區域,調整區域邊框寬度2px)
/// </summary>
private Rectangle cutImageRect = new Rectangle(0, 0, 5, 5);
#endregion
定義列舉型別:更新UI的模式
/// <summary>
/// 更新UI的模式,用於標記哪些需要顯示,哪些需要隱藏;
/// </summary>
[FlagsAttribute]
public enum UpdateUIMode : uint
{
//值得注意的是,如果要使用組合值,那麼就不能用連線的數字表示,必須是幾何級增長!
None = 0,
ShowTextPro = 1,
ShowPenStyle = 2,
ShowToolBox = 4,
ShowInfoBox = 8,
ShowZoomBox = 16,
ShowCutImage = 32,
HideTextPro = 64,
HidePenStyle = 128,
HideToolBox = 256,
HideInfoBox = 512
}
新增方法:計算並儲存截圖的區域框的大小
/// <summary>
/// 計算並儲存截圖的區域框的大小
/// </summary>
private void SaveCutImageSize(Point beginPoint, Point endPoint)
{
// 儲存最終的繪圖基點,用於擷取選中的區域
this.endPoint = beginPoint;
// 計算擷取圖片的大小
int imgWidth = Math.Abs(endPoint.X - beginPoint.X) + 1;
int imgHeight = Math.Abs(endPoint.Y - beginPoint.Y) + 1;
int lblWidth = imgWidth + 4;
int lblHeight = imgHeight + 4;
// 設定截圖區域的位置和大小
this.cutImageRect = new Rectangle(beginPoint.X - 2, beginPoint.Y - 2, lblWidth, lblHeight);
}
新增方法:執行截圖,將選定區域的圖片儲存到剪貼簿
/// <summary>
/// 執行截圖,將選定區域的圖片儲存到剪貼簿
/// </summary>
/// <param name="saveToDisk">
/// 是否將圖片儲存到磁碟
/// </param>
private void ExecCutImage(bool saveToDisk, bool uploadImage) //bool saveToDisk = false, bool uploadImage = false
{
// 如果圖片獲取區域不可見,則退出儲存圖片過程
if (!this.lbl_CutImage.Visible) { return; }
Rectangle srcRect = new Rectangle();
srcRect.X = this.lbl_CutImage.Location.X + 2;
srcRect.Y = this.lbl_CutImage.Location.Y + 2;
srcRect.Width = this.lbl_CutImage.Width - 4;
srcRect.Height = this.lbl_CutImage.Height - 4;
Rectangle destRect = new Rectangle(0, 0, srcRect.Width, srcRect.Height);
Bitmap bmp = new Bitmap(srcRect.Width, srcRect.Height);
Graphics g = Graphics.FromImage(bmp);
g.DrawImage(this.screenImage, destRect, srcRect, GraphicsUnit.Pixel);
Clipboard.SetImage(bmp);
ExitCutImage(true);
}
新增方法:退出截圖過程
/// <summary>
/// 退出截圖過程
/// </summary>
private void ExitCutImage(bool hideWindow) // = true
{
this.lbl_CutImage.Visible = false;
this.isCuting = false;
if (hideWindow)
{
this.screenImage.Dispose();
this.Hide();
}
}
主視窗滑鼠按下事件處理程式
/// <summary>
/// 截圖視窗滑鼠按下事件處理程式
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
// 左鍵單擊事件
if (e.Button == MouseButtons.Left && e.Clicks == 1)
{
if (!this.lbl_CutImage.Visible)
{
this.isCuting = true;
this.beginPoint = e.Location;
this.endPoint = e.Location;
SaveCutImageSize(e.Location, e.Location);
UpdateCutInfoLabel(UpdateUIMode.ShowCutImage | UpdateUIMode.ShowInfoBox);
}
}
// 左鍵雙擊事件
if (e.Button == MouseButtons.Left && e.Clicks == 2)
{
if (this.lbl_CutImage.Visible)
{
ExecCutImage(false, false);
}
}
// 右鍵單擊事件
if (e.Button == MouseButtons.Right)
{
ExitCutImage(!this.lbl_CutImage.Visible);
}
}
主視窗滑鼠移動事件處理程式
/// <summary>
/// 截圖視窗滑鼠移動事件處理程式
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
// 如果擷取區域不可見,則退出處理過程
if (!this.lbl_CutImage.Visible)
{
UpdateCutInfoLabel(UpdateUIMode.None);
return;
}
Point pntBgn = this.beginPoint;
Point pntEnd = e.Location;
// 如果是反向拖動,重新設定起始點
if (e.Location.X < this.beginPoint.X && e.Location.Y < this.beginPoint.Y)
{
pntBgn = e.Location;
pntEnd = this.beginPoint;
}
else
{
if (e.Location.X < this.beginPoint.X)
{
pntBgn = new Point(e.Location.X, this.beginPoint.Y);
pntEnd = new Point(this.beginPoint.X, e.Location.Y);
}
else
{
if (e.Location.Y < this.beginPoint.Y)
{
pntBgn = new Point(this.beginPoint.X, e.Location.Y);
pntEnd = new Point(e.Location.X, this.beginPoint.Y);
}
}
}
if (this.isCuting)
{
SaveCutImageSize(pntBgn, pntEnd);
}
UpdateCutInfoLabel(UpdateUIMode.None);
}
主視窗滑鼠抬起事件處理程式
/// <summary>
/// 截圖視窗滑鼠抬起事件處理程式
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (this.isCuting)
{
this.isCuting = false;
UpdateCutInfoLabel(UpdateUIMode.None);
}
}
}
擷取區域圖片繪製
/// <summary>
/// 擷取區域圖片的繪製事件處理程式
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lbl_CutImage_Paint(object sender, PaintEventArgs e)
{
int imgWidth = this.lbl_CutImage.Width - 4;
int imgHeight = this.lbl_CutImage.Height - 4;
if (imgWidth < 1) { imgWidth = 1; }
if (imgHeight < 1) { imgHeight = 1; }
// 建立快取影象,先將要繪製的內容全部繪製到快取中,最後再一次性繪製到 Label 上,
// 這樣可以提高效能,並且可以防止螢幕閃爍的問題
Bitmap bmp_lbl = new Bitmap(this.lbl_CutImage.Width, this.lbl_CutImage.Height);
Graphics g = Graphics.FromImage(bmp_lbl);
// 將要擷取的部分繪製到快取
Rectangle destRect = new Rectangle(2, 2, imgWidth, imgHeight);
Point srcPoint = this.lbl_CutImage.Location;
srcPoint.Offset(2, 2);
Rectangle srcRect = new Rectangle(srcPoint, new System.Drawing.Size(imgWidth, imgHeight));
g.DrawImage(this.screenImage, destRect, srcRect, GraphicsUnit.Pixel);
SolidBrush brush = new SolidBrush(Color.FromArgb(10, 124, 202));
Pen pen = new Pen(brush, 1.0F);
//以下部分(邊框和調整塊)的繪製放在(編輯內容)的後面,是解決繪製編輯內容會覆蓋(邊框和調整塊)的問題
// 繪製邊框外的區域,解決會被編輯內容覆蓋的問題
// 上邊
destRect = new Rectangle(0, 0, this.lbl_CutImage.Width, 2);
srcPoint = this.lbl_CutImage.Location;
//srcPoint.Offset(2, 2);
srcRect = new Rectangle(srcPoint, new System.Drawing.Size(this.lbl_CutImage.Width, 2));
g.DrawImage(this.BackgroundImage, destRect, srcRect, GraphicsUnit.Pixel);
// 下邊
destRect = new Rectangle(0, this.lbl_CutImage.Height - 2, this.lbl_CutImage.Width, 2);
srcPoint = this.lbl_CutImage.Location;
srcPoint.Offset(0, this.lbl_CutImage.Height - 2);
srcRect = new Rectangle(srcPoint, new System.Drawing.Size(this.lbl_CutImage.Width, 2));
g.DrawImage(this.BackgroundImage, destRect, srcRect, GraphicsUnit.Pixel);
// 左邊
destRect = new Rectangle(0, 2, 2, this.lbl_CutImage.Height - 4);
srcPoint = this.lbl_CutImage.Location;
srcPoint.Offset(0, 2);
srcRect = new Rectangle(srcPoint, new System.Drawing.Size(2, this.lbl_CutImage.Height - 4));
g.DrawImage(this.BackgroundImage, destRect, srcRect, GraphicsUnit.Pixel);
// 右邊
destRect = new Rectangle(this.lbl_CutImage.Width - 2, 2, 2, this.lbl_CutImage.Height - 4);
srcPoint = this.lbl_CutImage.Location;
srcPoint.Offset(this.lbl_CutImage.Width - 2, 2);
srcRect = new Rectangle(srcPoint, new System.Drawing.Size(2, this.lbl_CutImage.Height - 4));
g.DrawImage(this.BackgroundImage, destRect, srcRect, GraphicsUnit.Pixel);
// 繪製邊框
g.DrawLine(pen, 2, 2, this.lbl_CutImage.Width - 3, 2);
g.DrawLine(pen, 2, 2, 2, this.lbl_CutImage.Height - 3);
g.DrawLine(pen, this.lbl_CutImage.Width - 3, 2, this.lbl_CutImage.Width - 3, this.lbl_CutImage.Height - 3);
g.DrawLine(pen, 2, this.lbl_CutImage.Height - 3, this.lbl_CutImage.Width - 3, this.lbl_CutImage.Height - 3);
// 繪製四個角的調整塊
g.FillRectangle(brush, 0, 0, 4, 5);
g.FillRectangle(brush, this.lbl_CutImage.Width - 4, 0, 4, 5);
g.FillRectangle(brush, 0, this.lbl_CutImage.Height - 5, 4, 5);
g.FillRectangle(brush, this.lbl_CutImage.Width - 4, this.lbl_CutImage.Height - 5, 4, 5);
// 繪製中間的四個調整塊
int blockX = this.lbl_CutImage.Width / 2 - 2;
int blockY = this.lbl_CutImage.Height / 2 - 2;
g.FillRectangle(brush, blockX, 0, 4, 5);
g.FillRectangle(brush, 0, blockY, 4, 5);
g.FillRectangle(brush, blockX, this.lbl_CutImage.Height - 5, 4, 5);
g.FillRectangle(brush, this.lbl_CutImage.Width - 4, blockY, 4, 5);
// 繪製到 Label 上
e.Graphics.DrawImage(bmp_lbl, 0, 0);
bmp_lbl.Dispose();
}
雙擊滑鼠左鍵完成截圖功能
/// <summary>
/// 擷取區域圖片的滑鼠按下事件處理程式
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lbl_CutImage_MouseDown(object sender, MouseEventArgs e)
{
// 左鍵雙擊事件
if (e.Button == MouseButtons.Left && e.Clicks == 2)
{
if (this.lbl_CutImage.Visible)
{
ExecCutImage(false, false);
}
}
}
注意:程式碼都貼完了,別忘了為窗體或元件繫結事件處理程式;
例如:擷取區域圖片的滑鼠按下事件處理程式“lbl_CutImage_MouseDown”,就是“lbl_CutImage”元件的“MouseDown”事件的處理程式,繫結方法參考下圖:
到此,基本截圖的功能實現已經實現,趕快去擷取一張圖片,貼上到QQ的聊天視窗看看吧。
原始碼下載:http://download.csdn.net/detail/testcs_dn/7261365
相關文章
- C#軟體開發例項.私人訂製自己的螢幕截圖工具(一)功能概覽C#
- C#軟體開發例項.私人訂製自己的螢幕截圖工具(六)新增配置管理功能C#
- C#軟體開發例項.私人訂製自己的螢幕截圖工具(三)托盤圖示及選單的實現C#
- C#軟體開發例項.私人訂製自己的螢幕截圖工具(二)建立專案、註冊熱鍵、顯示截圖主視窗...C#
- C#軟體開發例項.私人訂製自己的螢幕截圖工具(五)針對拖拽時閃爍卡頓現象的優化...C#優化
- SPX螢幕截圖軟體
- Python網頁截圖/螢幕截圖/截長圖如何實現?Python網頁
- selenium實現螢幕截圖
- C#實現截圖功能C#
- 用electron開發了一個螢幕截圖工具
- iSnapshot for Mac螢幕截圖工具Mac
- 高畫質螢幕截圖工具GrabIt ,體驗不一樣的截圖感受
- Android 5.0 螢幕錄製/截圖Android
- 最強大的螢幕截圖軟體:Snagit for macGitMac
- Mac螢幕截圖工具——iSnapshot for MacMac
- iOS螢幕截圖的方法iOS
- 從0到1,手把手帶你開發截圖工具ScreenCap------001實現基本的截圖功能
- Snagit 2023 for Mac(螢幕截圖軟體)GitMac
- TechSmith Snagit mac最強大的螢幕截圖軟體MITGitMac
- C#實現網頁截圖功能C#網頁
- 全功能的螢幕截圖軟體:Snagit 2021 for Mac中文版GitMac
- 直播平臺軟體開發,完整擷取整個螢幕的截圖方式
- 少俠學截圖-C#螢幕捕捉的方式C#
- .NET 視窗/螢幕截圖
- Movavi Screen Recorder 22 Mac(螢幕錄影截圖軟體)Mac
- canvas實現截圖功能Canvas
- 螢幕截圖工具Snagit 2022 macGitMac
- TechSmith Snagit 2022螢幕截圖工具MITGit
- Snagit 2022 for Mac(螢幕截圖工具)GitMac
- android 螢幕截圖原始碼Android原始碼
- mac蘋果螢幕截圖快捷鍵Mac蘋果
- ScreenFloat for Mac(螢幕截圖軟體) 1.5.22啟用版Mac
- 掌握Snagit 2023:輕鬆實現螢幕錄製與截圖Git
- android截圖功能實現Android
- Snagit2024 螢幕錄製與截圖軟體mac/win啟用版GitMac
- Windows 8.1怎麼給螢幕截圖Windows
- Android螢幕截圖方式總結Android
- Ubuntu螢幕截圖快捷鍵知多少Ubuntu