原文: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 = ;
private int intStartY = ;
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, );
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 = ;
intStartY = ;
}

当然这只是在图片上画了一个红色的矩形,没法二次调整矩形大小,移动矩形,且画图时会不停的清除画下的痕迹,导致屏幕闪烁,且平时使用的屏幕截图在选择区的区域亮度都会高些,这些都没实现,不过既然能画区域了那这些就都不是问题了,只需稍作修改即可,以下给出部分修改代码:

填充选择区

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 - && p.X <= StartX && p.Y >= StartY - && p.Y <= StartY)
{this.Cursor = Cursors.SizeNWSE;
}
else if (p.X >= StartX + ScreenWidth && p.X <= StartX + ScreenWidth + && p.Y <= StartY + ScreenHeight + && p.Y >= StartY + ScreenHeight)
{this.Cursor = Cursors.SizeNWSE;
}
else if ((p.X >= StartX + ScreenWidth && p.X <= StartX + ScreenWidth + && p.Y >= StartY - && p.Y <= StartY))
{this.Cursor = Cursors.SizeNESW;
}
else if (p.X >= StartX - && p.X <= StartX && p.Y <= StartY + ScreenHeight + && 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);

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

winform屏幕截图的更多相关文章

  1. Winform屏幕截图保存C#代码

    代码如下: using System.Runtime.InteropServices; using System.Drawing.Imaging; [System.Runtime.InteropSer ...

  2. 16Aspx.com源码2014年7月详细

            Web电子商务网(三层)V2.0源码 2014-07-31   [VS2010] 源码介绍: Web电子商务网(三层)V2.0源码 源码描述: 一.源码特点     采用三层架构开发, ...

  3. WinForm GDI+ 资料收集

    UI(User Interface)编程在整个项目开发过程中是个颇为重要的环节,任何好的解决方案若没有良好的用户界面呈现给最终用户,那么就算包含了最先进的技术也不能算是好程序.UI编程体现在两个方面, ...

  4. winform实现矩形框截图

    使用方法如下: private void button1_Click(object sender, EventArgs e) { s.GerScreenFormRectangle(); } priva ...

  5. C# WinForm开发系列 - GDI+【转】

    http://blog.csdn.net/blue_sky6/article/details/53811435?locationNum=6&fps=1 C# WinForm开发系列 - GDI ...

  6. 解决WinForm屏幕缩放适配只需修改两个Form的两个属性

    最近要做一个windows下截屏识别文字的程序,调试发现截取的图像显示不完整. 输出了Screen.PrimaryScreen.Bounds.Width获取的值,结果与实际分辨率不同,所以确定了与我的 ...

  7. 使用Python保存屏幕截图(不使用PIL)

    起因 在极客学院讲授<使用Python编写远程控制程序>的课程中,涉及到查看被控制电脑屏幕截图的功能. 如果使用PIL,这个需求只需要三行代码: from PIL import Image ...

  8. 使用 .NET WinForm 开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用程序

    直接切入正题,这是我09年到11年左右业余时间编写的项目,最初的想法很简单,做一个能拖拖拽拽就直接生成应用程序的工具,不用写代码,把能想到的业务操作全部封装起来,通过配置的方式把这些业务操作组织起来运 ...

  9. 逆天通用水印支持Winform,WPF,Web,WP,Win10。支持位置选择(9个位置 ==》[X])

    常用技能:http://www.cnblogs.com/dunitian/p/4822808.html#skill 逆天博客:http://dnt.dkil.net 逆天通用水印扩展篇~新增剪贴板系列 ...

随机推荐

  1. 【新秀疯狂UML系列】——面向对象的技术

    从软质工作开始,我们来到与面向对象的接触,接下来的学习材料似乎已经提到了面向对象,在与她的朋友去一个.所以,我们必须知道她多一点点. 一.何为面向对象? 面向对象(Object Oriented).是 ...

  2. window下自己主动备份数据库成dmp格式的bat写法

    复制以下的命令到一个txt文本文档,然后改动相应的參数为自己须要的參数,一切完毕之后,将文件保存为bat格式. 这样每次须要备份的时候仅仅须要双击一下这个bat文件.其它的都不用你了,你仅仅须要静静的 ...

  3. cocos2d-x 3.1.1 学习笔记[21]cocos2d-x 创建过程

    文章出自于  http://blog.csdn.net/zhouyunxuan RootViewController.h #import <UIKit/UIKit.h> @interfac ...

  4. Demo of Python &quot;Map Reduce Filter&quot;

    Here I share with you a demo for python map, reduce and filter functional programming thatowned by m ...

  5. Cocos2d-iPhone V3 (1) 其基本程序常用的行动框架和介绍

    Cocos2d-iPhone V3 (1) 其基本程序常用的行动框架和介绍 博客:http://blog.csdn.net/prevention 笔者:犀利哥 - 第一部分:一个 Cocos2d-iP ...

  6. C#基础之二

    C#基础之二 1.  静态字段.静态成员:由该类的所有实例共享,其变化,实例是对所有可见. 2.  声明为static有:场.方法.属性.构造函数.运营商.事件. 3.  不同的常量静态量:位置,在编 ...

  7. 【LeetCode】3Sum 解决报告

    这个问题是我目前的知识回答,不来,只有良好的网上搜索解决方案,发现 K Sum 它是一类问题,但是,互联网是没有更简洁的代码,我想对于谁刚开始学习的人.您可能仍然想看看这个问题该怎么解决,然后看看他们 ...

  8. head first c&lt;11&gt;在根据网络编程

    博文可以在一个大的网络通信实现,但是,一个人只能起到,我们能够给每个clientfork()子进程,实现诸多的服务. 方法: client连到server以后,server启动一个新创建的套接字对话. ...

  9. JavaScript的隐式转换

    原文:JavaScript的隐式转换 JavaScript的数据类型分为六种,分别为null,undefined,boolean,string,number,object.object是引用类型,其它 ...

  10. C++ Primer 学习笔记_43_STL实践与分析(17)--再谈迭代器【中】

    STL实践与分析 --再谈迭代器[中] 二.iostream迭代[续] 3.ostream_iterator对象和ostream_iterator对象的使用 能够使用ostream_iterator对 ...