屏幕截图是一个比较经常使用的功能,在项目中出现的比例也比较高,至少我作过的每一个项目都有屏幕截图这个功能,从全屏截图到区域截图都有出现过。固然区域截图已然包含了全屏截图。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);
这样便可实现简单的区域截图了。