winform屏幕截圖


屏幕截圖是一個比較常用的功能,在項目中出現的比例也比較高,至少我做過的每個項目都有屏幕截圖這個功能,從全屏截圖到區域截圖都有出現過。當然區域截圖已然包含了全屏截圖。

全屏截圖方式有好幾種,調用API截圖、調用操作系統的截圖然后到剪切板去取(當然這種方式幾乎沒人會去用)、用Graphics去畫屏幕等等。

下面上Graphics畫屏幕的代碼,畢竟這種方式代碼量最少。

            //截取屏幕
            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呢)

實現區域截圖,主要有四個步驟,一截取全屏,彈出遮罩層,畫選擇區,截取選擇區域

一、截取全屏可用上面代碼實現,這里就不寫了。

二、彈出遮罩層

     遮罩層的目的是用來畫截圖區域,一般采用半透明方式。代碼如下:

            this.BackColor = Color.Gray;
            this.Opacity = 0.5;
            this.FormBorderStyle = FormBorderStyle.None;
            this.WindowState = FormWindowState.Maximized;

  設置窗體背景顏色,通明度,邊框樣式及使其最大化。即可彈出全屏遮罩層。

三、畫選擇區

  這個就是截屏中最重要的部分了

  我們需要在窗體中加入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個角,只需將起始坐標設置好之后和原來一樣畫區域就行,若是在區域中,移動選擇區則需根據當前坐標和開始坐標計算出差值,在移動時更改開始坐標,固定寬高畫區域即可,若移動到屏幕邊緣需加上判斷。

四、截取選擇區域

畫好區域后,需要選擇是否截取,通常會給出按鈕選擇我們只需在MouseUP和MouseDown事件中加上按鈕的隱藏和顯示即可,顯示時根據選擇區計算顯示的坐標位置。

截取選擇區代碼

Bitmap map = myImage.Clone(new Rectangle(StartX, StartY, ScreenWidth, ScreenHeight), System.Drawing.Imaging.PixelFormat.Format32bppArgb);

這樣即可實現簡單的區域截圖了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM