屏幕截圖是一個比較經常使用的功能,在項目中出現的比例也比較高,至少我作過的每一個項目都有屏幕截圖這個功能,從全屏截圖到區域截圖都有出現過。固然區域截圖已然包含了全屏截圖。windows
全屏截圖方式有好幾種,調用API截圖、調用操做系統的截圖而後到剪切板去取(固然這種方式幾乎沒人會去用)、用Graphics去畫屏幕等等。this
下面上Graphics畫屏幕的代碼,畢竟這種方式代碼量最少。spa
//截取屏幕 Bitmap myImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Graphics g = Graphics.FromImage(myImage); g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)); g.Dispose();
上面的代碼便可截取當前屏幕的圖像。注:因爲WPF是使用DirectX進行渲染的,此方式截圖在部分系統會截圖不到wpf的窗體。(win7,windows server2008,windows vista均能截取到wpf窗體,windows XP沒法截取到WPF窗體,緣由多是windows xp出現時尚未WPF呢)操作系統
實現區域截圖,主要有四個步驟,一截取全屏,彈出遮罩層,畫選擇區,截取選擇區域code
1、截取全屏可用上面代碼實現,這裏就不寫了。orm
2、彈出遮罩層server
遮罩層的目的是用來畫截圖區域,通常採用半透明方式。代碼以下:blog
this.BackColor = Color.Gray; this.Opacity = 0.5; this.FormBorderStyle = FormBorderStyle.None; this.WindowState = FormWindowState.Maximized;
設置窗體背景顏色,通明度,邊框樣式及使其最大化。便可彈出全屏遮罩層。事件
3、畫選擇區圖片
這個就是截屏中最重要的部分了
咱們須要在窗體中加入pictureBox控件,且Dock屬性設置爲Fill,這樣才能在屏幕上畫選擇區
跟隨鼠標在 pictureBox的圖片上畫矩形 private int intStartX = 0; private int intStartY = 0; private bool isMouseDraw = false; private void pictureBox_Src_MouseDown(object sender, MouseEventArgs e) { isMouseDraw = true; intStartX = e.X; intStartY = e.Y; } private void pictureBox_Src_MouseMove(object sender, MouseEventArgs e) { if (isMouseDraw) { try { Graphics g = this.pictureBox_Src.CreateGraphics(); //清空上次畫下的痕跡 g.Clear(this.pictureBox_Src.BackColor); Brush brush = new SolidBrush(Color.Red); Pen pen = new Pen(brush, 1); pen.DashStyle = DashStyle.Solid; g.DrawRectangle(pen, new Rectangle(intStartX > e.X ? e.X : intStartX, intStartY > e.Y ? e.Y : intStartY, Math.Abs(e.X - intStartX), Math.Abs(e.Y - intStartY))); g.Dispose(); } catch (Exception ex) { ex.ToString(); } } } private void pictureBox_Src_MouseUp(object sender, MouseEventArgs e) { isMouseDraw = false; intStartX = 0; intStartY = 0; }
固然這只是在圖片上畫了一個紅色的矩形,無法二次調整矩形大小,移動矩形,且畫圖時會不停的清除畫下的痕跡,致使屏幕閃爍,且平時使用的屏幕截圖在選擇區的區域亮度都會高些,這些都沒實現,不過既然能畫區域了那這些就都不是問題了,只需稍做修改便可,如下給出部分修改代碼:
填充選擇區
SolidBrush soldwhite = new SolidBrush(Color.White); Rectangle rec = new Rectangle(StartX, StartY, ScreenWidth, ScreenHeight); g.FillRectangle(soldwhite, rec);//用來填充矩形區域
屏幕閃爍
清除時屏幕閃爍是因爲清除的整個圖片,而後在從新繪製的,這樣若加上填充區設置爲白色,咱們能看到填充區域閃爍的很厲害,解決方式爲採用填充的方式清除選擇區域外的部分,這樣整個圖片總共分5此填充和一次劃線。
Graphics g = this.pictureBox1.CreateGraphics(); //清空上次畫下的痕跡 // g.Clear(this.pictureBox1.BackColor); g.FillRectangle(soldgray, 0, 0, pictureBox1.Width, StartY);//清除上 g.FillRectangle(soldgray, 0, StartY + ScreenHeight, pictureBox1.Width, pictureBox1.Height - (StartY + ScreenHeight));//清除下 g.FillRectangle(soldgray, 0, StartY, StartX, ScreenHeight + 1);//清除左 g.FillRectangle(soldgray, StartX + ScreenWidth, StartY, pictureBox1.Width - (StartX + ScreenWidth), ScreenHeight + 1);//清除右
二次調整大小及選擇區移動
當咱們對區域進行選擇後,想二次調整大小一般會看到鼠標樣式變化,表示能夠對其進行修改或移動
/// <summary> /// 設置鼠標樣式 /// </summary> /// <param name="p"></param> private void SetCursorStyle(Point p) { if (p.X > StartX && p.X < StartX + ScreenWidth && p.Y > StartY && p.Y < StartY + ScreenHeight) {this.Cursor = Cursors.SizeAll; } else if (p.X >= StartX - 10 && p.X <= StartX && p.Y >= StartY - 10 && p.Y <= StartY) {this.Cursor = Cursors.SizeNWSE; } else if (p.X >= StartX + ScreenWidth && p.X <= StartX + ScreenWidth + 10 && p.Y <= StartY + ScreenHeight + 10 && p.Y >= StartY + ScreenHeight) {this.Cursor = Cursors.SizeNWSE; } else if ((p.X >= StartX + ScreenWidth && p.X <= StartX + ScreenWidth + 10 && p.Y >= StartY - 10 && p.Y <= StartY)) {this.Cursor = Cursors.SizeNESW; } else if (p.X >= StartX - 10 && p.X <= StartX && p.Y <= StartY + ScreenHeight + 10 && p.Y >= StartY + ScreenHeight) {this.Cursor = Cursors.SizeNESW; } else {this.Cursor = Cursors.Default; } }
這是設置鼠標在選擇區域內的樣式和四個角的樣式,如果在4個角,只需將起始座標設置好以後和原來同樣畫區域就行,如果在區域中,移動選擇區則需根據當前座標和開始座標計算出差值,在移動時更改開始座標,固定寬高畫區域便可,若移動到屏幕邊緣需加上判斷。
4、截取選擇區域
畫好區域後,須要選擇是否截取,一般會給出按鈕選擇咱們只需在MouseUP和MouseDown事件中加上按鈕的隱藏和顯示便可,顯示時根據選擇區計算顯示的座標位置。
截取選擇區代碼
Bitmap map = myImage.Clone(new Rectangle(StartX, StartY, ScreenWidth, ScreenHeight), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
這樣便可實現簡單的區域截圖了。