博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
winform屏幕截图
阅读量:5305 次
发布时间:2019-06-14

本文共 5015 字,大约阅读时间需要 16 分钟。

屏幕截图是一个比较常用的功能,在项目中出现的比例也比较高,至少我做过的每个项目都有屏幕截图这个功能,从全屏截图到区域截图都有出现过。当然区域截图已然包含了全屏截图。

全屏截图方式有好几种,调用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);//清除右

二次调整大小及选择区移动

当我们对区域进行选择后,想二次调整大小通常会看到鼠标样式变化,表示可以对其进行修改或移动

///         /// 设置鼠标样式        ///         ///         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);

这样即可实现简单的区域截图了。

转载于:https://www.cnblogs.com/fuchao2014/p/3781481.html

你可能感兴趣的文章
HTML5系列一(属性概述)
查看>>
大话设计模式--Python
查看>>
HOW TO UPGRADE GHOST ON OPENSHIFT
查看>>
python之路:数据类型初识
查看>>
Maven------使用maven新建web项目出现问题 项目名称出现红色交叉
查看>>
基础学习:C#中float的取值范围和精度
查看>>
Akka-Cluster(3)- ClusterClient, 集群客户端
查看>>
理解rem实现响应式布局原理及js动态计算rem
查看>>
基本数据类型编程练习一
查看>>
12C 启用客户端通过SID 连接PDB,防止ORA-12545
查看>>
java中基本数据类型和包装类的区别
查看>>
项目指南
查看>>
浅谈USB驱动架构 转载
查看>>
android SharedPreferences的用法
查看>>
PENETRATION TESTING PRACTICE LAB - VULNERABLE APPS / SYSTEMS
查看>>
JavaScript获取鼠标位置的三种方法
查看>>
HDU 4635 Strongly connected (强连通分量)
查看>>
USACO / Stringsobits (DP构造/康托展开)
查看>>
康托展开
查看>>
如何写用户导向的互联网文案?
查看>>