前兩篇已經基本向大家介紹了繪圖的基本知識.那麼,我就用我們上兩篇所學的,做幾個例子.
我們先來做一個簡單的----仿QQ截圖,關於這個的例子其實網上已經有這方面的資料了,但是為了文章的完整性,還是覺得有必要講解.
我們先來看看效果:
接下來看一下這就是如何做到的.
接下來看一下這就是如何做到的. 圖〜 畫在一個新的全屏窗體上,然後顯示這個窗體.因為是全屏的窗體,並且隱藏了菜單欄、工具列等,所以在我們看來就好像是一個桌面的截圖,然後在這個新窗體上畫矩形,最後保存矩形中的內容並顯示在原來的聊天窗體中.
步驟:
A.新建一個窗體.命名為Catch.然後設定這個窗體的FormBorderStyle為None,WindowState為Maximized.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace Client { public partial class Catch : Form { public Catch() { InitializeComponent(); } 用户变量 //窗体初始化操作 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) {//如果捕捉开始 Bitmap destBmp = (Bitmap)originBmp.Clone();//新建一个图片对象,并让它与原始图片相同 Point newPoint = new Point(DownPoint.X, DownPoint.Y);//获取鼠标的坐标 Graphics g = Graphics.FromImage(destBmp);//在刚才新建的图片上新建一个画板 Pen p = new Pen(Color.Blue,1); int width = Math.Abs(e.X - DownPoint.X), height = Math.Abs(e.Y - DownPoint.Y);//获取矩形的长和宽 if (e.X < DownPoint.X) { newPoint.X = e.X; } if (e.Y < DownPoint.Y) { newPoint.Y = e.Y; } CatchRect = new Rectangle(newPoint,new Size(width,height));//保存矩形 g.DrawRectangle(p,CatchRect);//将矩形画在这个画板上 g.Dispose();//释放目前的这个画板 p.Dispose(); Graphics g1 = this.CreateGraphics();//重新新建一个Graphics类 //如果之前那个画板不释放,而直接g=this.CreateGraphics()这样的话无法释放掉第一次创建的g,因为只是把地址转到新的g了.如同string一样 g1 = this.CreateGraphics();//在整个全屏窗体上新建画板 g1.DrawImage(destBmp,new Point(0,0));//将刚才所画的图片画到这个窗体上 //这个也可以属于二次缓冲技术,如果直接将矩形画在窗体上,会造成图片抖动并且会有无数个矩形. g1.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 (CatchRect.Contains(new Point(e.X, e.Y))) { Bitmap CatchedBmp = new Bitmap(CatchRect.Width, CatchRect.Height);//新建一个于矩形等大的空白图片 Graphics g = Graphics.FromImage(CatchedBmp); g.DrawImage(originBmp, new Rectangle(0, 0, CatchRect.Width, CatchRect.Height), CatchRect, GraphicsUnit.Pixel); //把orginBmp中的指定部分按照指定大小画在画板上 Clipboard.SetImage(CatchedBmp);//将图片保存到剪贴板 g.Dispose(); CatchFinished = false; this.BackgroundImage = originBmp; CatchedBmp.Dispose(); this.DialogResult = DialogResult.OK; this.Close(); } } } } }C.創建了Catch窗體後,我們在截圖按鈕(位於聊天窗體上)上加入以下事件:
private void bCatch_Click(object sender, EventArgs e) { if (bCatch_HideCurrent.Checked) { this.Hide();//隐藏当前窗体 Thread.Sleep(50);//让线程睡眠一段时间,窗体消失需要一点时间 Catch CatchForm = new Catch(); 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));//保存全屏图片 CatchForm.BackgroundImage = CatchBmp;//将Catch窗体的背景设为全屏时的图片 if (CatchForm.ShowDialog() == DialogResult.OK) {//如果Catch窗体结束,就将剪贴板中的图片放到信息发送框中 IDataObject iData = Clipboard.GetDataObject(); DataFormats.Format myFormat = DataFormats.GetFormat(DataFormats.Bitmap); if (iData.GetDataPresent(DataFormats.Bitmap)) { richtextbox1.Paste(myFormat); Clipboard.Clear();//清除剪贴板中的对象 } this.Show();//重新显示窗体 } } }