C# GDI+实现截图功能源码
2013-06-27 10:16
253 查看
代码内容来自于 “我不是圣人” 博客。地址:点击打开链接
他的原理及实现细节都讲得非常详细。我把他的源码优化了下,贴出来给GDI+新手学习。
在读此代码前,必须先读他的博客,这一点切记。
截屏窗体:
OK,响应截图事件:
他的原理及实现细节都讲得非常详细。我把他的源码优化了下,贴出来给GDI+新手学习。
在读此代码前,必须先读他的博客,这一点切记。
截屏窗体:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Drawing.Drawing2D; namespace WindowsFormsApplication2 { public partial class Catch : Form { public Catch() { InitializeComponent(); } #region 用户变量 private Point _downPoint = Point.Empty;//记录鼠标按下坐标,用来确定绘图起点 private bool _catchFinished = false;//用来表示是否截图完成 private bool _catchStart = false;//表示截图开始 private Bitmap _originBmp;//用来保存原始图像 private Rectangle _catchRectangle;//用来保存截图的矩形 #endregion //窗体初始化操作 private void Catch_Load(object sender, EventArgs e) { this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true); this.UpdateStyles(); //以上两句是为了设置控件样式为双缓冲,这可以有效减少图片闪烁的问题,关于这个大家可以自己去搜索下 _originBmp = new Bitmap(this.BackgroundImage);//BackgroundImage为全屏图片,我们另用变量来保存全屏图片 } //鼠标右键点击结束截图;没有直接的右键相应事件 private void Catch_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { this.DialogResult = DialogResult.OK; this.Close(); } } //鼠标左键按下时动作 private void Catch_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { if (!_catchStart) { //如果捕捉没有开始 _catchStart = true; _downPoint = new Point(e.X, e.Y);//保存鼠标按下坐标 } } } private void Catch_MouseMove(object sender, MouseEventArgs e) { //如果捕捉开始 if (_catchStart) { Point newStartPoint = new Point(_downPoint.X, _downPoint.Y); //如果是反向截图,终点就变成了起点,无论如何,长度和宽度是绝对值,都是从左向右、从上往下画 if (e.X < _downPoint.X) { newStartPoint.X = e.X; } if (e.Y < _downPoint.Y) { newStartPoint.Y = e.Y; } //获取矩形的长和宽 int width = Math.Abs(e.X - _downPoint.X); int height = Math.Abs(e.Y - _downPoint.Y); Bitmap destBmp = (Bitmap)_originBmp.Clone(); Graphics g = Graphics.FromImage(destBmp); Pen p = new Pen(Color.Blue, 1); _catchRectangle = new Rectangle(newStartPoint, new Size(width, height)); g.DrawRectangle(p, _catchRectangle); g.Dispose(); p.Dispose(); //如果之前那个画板不释放,而直接g=this.CreateGraphics()这样的话无法释放掉第一次创建的g,因为只是把地址转到新的g了.如同string一样 Graphics gNew = this.CreateGraphics(); gNew.DrawImage(destBmp, new Point(0, 0));//这个也可以属于二次缓冲技术,如果直接将矩形画在窗体上,会造成图片抖动并且会有无数个矩形. gNew.Dispose(); destBmp.Dispose();//要及时释放,不然内存将会被大量消耗 } } private void Catch_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { if (_catchStart) { _catchStart = false; _catchFinished = true; } } } //鼠标双击事件,如果鼠标位于矩形内,则将矩形内的图片保存到剪贴板中 private void Catch_MouseDoubleClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left && _catchFinished) { if (_catchRectangle.Contains(new Point(e.X, e.Y))) { Bitmap cachedBmp = new Bitmap(_catchRectangle.Width, _catchRectangle.Height);//新建一个于矩形等大的空白图片 Graphics g = Graphics.FromImage(cachedBmp); g.DrawImage(_originBmp, new Rectangle(0, 0, _catchRectangle.Width, _catchRectangle.Height), _catchRectangle, GraphicsUnit.Pixel);//把orginBmp中的指定部分按照指定大小画在画板上 Clipboard.SetImage(cachedBmp);//将图片保存到剪贴板 g.Dispose(); _catchFinished = false; this.BackgroundImage = _originBmp; cachedBmp.Dispose(); this.DialogResult = DialogResult.OK; this.Close(); } } } } }
OK,响应截图事件:
private void button3_Click(object sender, EventArgs e) { //this.Hide();//隐藏当前窗体 //Thread.Sleep(50);//让线程睡眠一段时间,窗体消失需要一点时间 Bitmap catchBmp = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);//新建一个和屏幕大小相同的图片 Graphics g = Graphics.FromImage(catchBmp); g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height));//保存全屏图片 Catch catchForm = new Catch(); catchForm.BackgroundImage = catchBmp;//将Catch窗体的背景设为全屏时的图片 if (catchForm.ShowDialog() == DialogResult.OK) { //如果Catch窗体结束,就将剪贴板中的图片放到richTextBox中去 IDataObject iData = Clipboard.GetDataObject(); DataFormats.Format myFormat = DataFormats.GetFormat(DataFormats.Bitmap); if (iData.GetDataPresent(DataFormats.Bitmap)) { this.richTextBox1.Paste(myFormat); Clipboard.Clear();//清除剪贴板中的对象 } // this.Show();//重新显示窗体 } }
相关文章推荐
- C# GDI+ 简单绘图 (三) 实现仿QQ截图功能
- C# GDI+ 简单绘图 (三) 实现仿QQ截图功能
- 【转】C# 实现完整功能的截图控件(4)-完整版
- 用C# 实现截图功能--转载
- C#实现的Windows剪贴板监视器功能实例【附demo源码下载】
- C# 实现完整功能的截图控件(1)-实现绘图工具栏控件
- C#实现QQ截图功能及相关问题
- C# 实现完整功能的截图控件(2)-实现颜色和字体选择控件
- 使用Java实现系统托盘功能的介绍(附源码以及截图)
- C#实现更改IP功能源码
- C# 实现截图软件功能实例代码
- C#实现外部图片的拖拽到应用程序的简单功能,附全部源码,供有需要的参考
- C#实现更改IP功能源码
- 【转载】用C#语言实现类似QQ的截图功能
- C#实现网页截图功能
- C# 实现截图软件功能
- c#实现魔兽(warIII)中显血和改键功能 (附源码)(Hook中start方法已改进)
- c#实现魔兽(warIII)中显血和改键功能 (附源码)(代码参考sohighthesky)
- C#实现更改IP功能源码
- C#实现的滚动网页截图功能示例