C# GDI+ 簡單繪圖 (三)

來源:互聯網
上載者:User
前兩篇已經基本向大家介紹了繪圖的基本知識.那麼,我就用我們上兩篇所學的,做幾個例子.
  我們先來做一個簡單的----仿QQ,關於這個的例子其實網上已經有這方面的資料了,但是為了文章的完整性,還是覺得有必要講解.
  我們先來看一下效果:


  接下來看看這是如何做到的. 
  思路:聊天表單上有一個按鈕,點擊按鈕後,程式將整個螢幕畫在一個新的全屏表單上,然後顯示這個表單.因為是全屏的表單,並且隱藏了功能表列、工具列等,所以在我們看來就好像是一個案頭的,然後在這個新表單上畫矩形,最後儲存矩形中的內容並顯示在原來的聊天表單中.
  步驟:
  A.建立一個表單.命名為Catch.然後設定這個表單的FormBorderStyle為None,WindowState為Maximized.
  B.我們對代碼進行編輯:

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();//重新顯示表單                }            }        }

 這樣我們的功能便完成了.
  我想對於初學者來說如何消去第一次繪製的圖片是個比較困難的問題.如果沒有採取措施,你會發現只要你滑鼠移動,就會畫一個矩形,這樣便會出現N多的矩形,而我們只是要最後的那一個.
  一般解決這種問題的方法有兩種:
  1.就是在繪製第二個圖形時,我們先用與底色相同的顏色將上次繪製的圖形重新繪製一下.但這往往需要底色為純色時使用.
  2.我們並不直接將圖形畫在畫板上,我們用一個圖片A來儲存原畫板上的圖片.然後再建立一個與圖片A相同的圖片B,將我們要繪製的圖形畫在該圖片B上,然後再將該圖片B畫在畫板上.這樣圖片A並沒有被改變.於是第二次畫的時候我們還是同樣建立一個與圖片A相同的圖片進行繪製.那麼上一次的圖形就不會被保留下來.問題也就解決了.

  下一次,向大家介紹如何做一個仿windows畫板的程式.


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.