接上一篇寫(xiě)的截取電腦屏幕,我們在原來(lái)的基礎上加一個(gè)選擇區域的功能,實(shí)現自定義選擇截圖。
個(gè)人比較懶,上一篇的代碼就不重新設計了,就簡(jiǎn)單改一下呈現方式。

不得不吐槽一下,在windows10系統上設置了放大比例的話(huà),用這種方式來(lái)實(shí)現截圖功能的話(huà)需要去計算比例。后面有機會(huì )的話(huà),用第三方DLL再實(shí)現一次。
實(shí)現功能:
屏幕選擇區域截圖
開(kāi)發(fā)環(huán)境:
開(kāi)發(fā)工具:Visual Studio 2013
.NET Framework版本:4.5
實(shí)現代碼:
//將上一篇的內容改成以下內容// pictureBox1.Image = bmp;Form2 frm = new Form2();frm.BaseImage = bmp;frm.TopMost = true;frm.Show();
/*Form2代碼*/#region Dll引用[DllImport("User32.dll", EntryPoint = "GetDC")]private extern static IntPtr GetDC(IntPtr hWnd);[DllImport("User32.dll", EntryPoint = "ReleaseDC")]private extern static int ReleaseDC(IntPtr hWnd, IntPtr hDC);[DllImport("gdi32.dll")]public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);[DllImport("User32.dll")]public static extern int GetSystemMetrics(int hWnd);const int DESKTOPVERTRES = 117;const int DESKTOPHORZRES = 118;const int SM_CXSCREEN = 0;const int SM_CYSCREEN = 1;#endregion//<summary>//獲取DPI縮放比例//</summary>//<param name="dpiscalex"></param>//<param name="dpiscaley"></param>public static void GetDPIScale(ref float dpiscalex, ref float dpiscaley){int x = GetSystemMetrics(SM_CXSCREEN);int y = GetSystemMetrics(SM_CYSCREEN);IntPtr hdc = GetDC(IntPtr.Zero);int w = GetDeviceCaps(hdc, DESKTOPHORZRES);int h = GetDeviceCaps(hdc, DESKTOPVERTRES);ReleaseDC(IntPtr.Zero, hdc);dpiscalex = (float)w / x;dpiscaley = (float)h / y;}public Bitmap BaseImage { get; set; }Graphics picGraphics;//記錄鼠標開(kāi)始截圖的位置int startX = 0, startY = 0;//記錄鼠標結束截圖的位置int endX = 0, endY = 0;//記錄DPI縮放比例float x = 0f, y = 0f;public Form2(){InitializeComponent();}private void Form2_Load(object sender, EventArgs e){/* 初始化賦值*/GetDPIScale(ref x, ref y);picGraphics = pictureBox1.CreateGraphics();}private void pictureBox1_Paint(object sender, PaintEventArgs e){DrawRect(endX - startX, endY - startY,e.Graphics);}private void Form2_KeyPress(object sender, KeyPressEventArgs e){//按下esc退出if (e.KeyChar == 27){this.Close();}}//完成截圖private void lbSucess_Click(object sender, EventArgs e){int clip_w = (int)((endX - startX) * x) - 4, clip_h = (int)((endY - startY) * y) - 4;if (clip_w < 1 || clip_h < 1){return;}//獲取截圖Bitmap clipBmp = new Bitmap(clip_w, clip_h);Graphics g = Graphics.FromImage(clipBmp);g.CopyFromScreen((int)(startX * x) + 2, (int)(startY * y) + 2, 0, 0, new Size(clip_w, clip_h), CopyPixelOperation.SourceCopy);//將截圖設置到剪切板Clipboard.SetImage(clipBmp);g.Dispose();this.Close();}private void pictureBox1_MouseDown(object sender, MouseEventArgs e){//隱藏操作面板panel1.Visible = false;//記錄鼠標開(kāi)始截圖的位置if (e.Button == MouseButtons.Left){startX = e.X;startY = e.Y;endX = 0; endY = 0;}}private void pictureBox1_MouseMove(object sender, MouseEventArgs e){if (e.Button == MouseButtons.Left){//繪制截圖區域DrawRect(e.X - startX, e.Y - startY, picGraphics);}}private void pictureBox1_MouseUp(object sender, MouseEventArgs e){//截圖完成if (e.Button == MouseButtons.Left){endX = e.X;endY = e.Y;DrawRect(endX - startX, endY - startY, picGraphics);if (endX > startX && endY > startY){//顯示操作面板Thread.Sleep(100);panel1.Location = new Point(e.X - panel1.Width, e.Y + 5);panel1.Visible = true;}}}//繪制截圖區域private void DrawRect(int w, int h,Graphics g){Bitmap img = (Bitmap)BaseImage.Clone();//雙緩沖技術(shù)畫(huà)矩形,防止重影和抖動(dòng)Graphics Painter = Graphics.FromImage(img);Painter.DrawRectangle(new Pen(Color.Red), startX * x, startY * y, w * x, h * y);g.DrawImage(img, 0, 0, img.Width / x, img.Height / y);Painter.Dispose();img.Dispose();}
實(shí)現效果:

我這邊演示代碼很少做異常處理(前面也是,后面也是,畢竟不是做項目為主),大家使用的時(shí)候根據情況自行處理下即可,亦或者可能會(huì )有內存未及時(shí)釋放的情況。
有朋友可能也看到演示效果中的另一個(gè)選項是文字識別,嗯,下一篇寫(xiě)OCR功能,直接將截圖中的數據轉化為文字。
由簡(jiǎn)入繁,拿來(lái)即用
后續精彩,持續關(guān)注
聯(lián)系客服