最近查閱網上資料,將GDI+的基本知識彙總以下:編程
1、基本的知識ide
GDI+:Graphics Device Interface Plus也就是圖形設備接口,提供了各類豐富的圖形圖像處理功能;函數
在C#.NET中,使用GDI+處理二維(2D)的圖形和圖像,使用DirectX處理三維(3D)的圖形圖像,this
圖形圖像處理用到的主要命名空間是System.Drawing,程序集:System.Drawing.d11:提供了對GDI+基本圖形功能的訪問,主要有Graphics類、Bitmap類、從Brush類繼承的類、Font類、Icon類、Image類、Pen類、Color類等.spa
1.1Graphics類線程
俗稱:畫布,用於在其上面繪製相應的圖像、圖片、文字等內容...有如下三種建立方式orm
(1)利用窗體或控件的Paint事件的參數PaintEventArgs建立Graphics對象。對象
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics; //建立畫板,這裏的畫板是由Form提供的.
}blog
(2)使用窗體或控件的CreateGraphics方法繼承
Graphics g=this.CreateGraphics();
Graphics g=this.button1.CreateGraphics();
(3)使用Image的派生類建立Graphics對象。使用Image的任何派生類都可以生成相應的Graphics對象,這種方法通常適用於在C#中對圖像進行處理的場合。
Bitmap b=new Bitmap("Mybmp.bmp");
Graphics g=Graphics.FromImage(b);
1.2 Pen對象
Pen類的構造函數有四種,使用方法以下。
(1)建立某一顏色的Pen對象:public Pen(Color)
(2)建立某一刷子樣式的Pen對象:public Pen(Brush)
(3)建立某—刷子樣式並具備相應寬度的Pen對象:public Pen(Brush,float)
(4)建立某一顏色和相應寬度的Pen對象:public Pen(Color,float)
Pen對象的經常使用屬性
(1)Alignment屬性:用來獲取或設置此Pen對象的對齊方式。
(2)Color屬性:用來獲取或設置此Pen對象的顏色。
(3)Width屬性:用來獲取或設置此Pen對象的寬度。
(4)DashStyle屬性:用來獲取或設置經過此Pen對象繪製的虛線的樣式。
(5)DashCap屬性:用來指定虛線兩端風格,是一個DashCap枚舉型的值。
(6)StartCap屬性:用來獲取或設置經過此Pen對象繪製的直線起點的帽樣式。
(7)EndCap屬性:用來獲取或設置經過此Pen對象繪製的直線終點的帽樣式。
(8)PenType屬性:用來獲取用此Pen對象繪製的直線的樣式。
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics; //建立畫板,這裏的畫板是由Form提供的.
Pen p = new Pen(Color.Blue, 2);//定義了一個藍色,寬度爲的畫筆
g.DrawLine(p, 10, 10, 100, 100);//在畫板上畫直線,起始座標爲(10,10),終點座標爲(100,100)
g.DrawRectangle(p, 10, 10, 100, 100);//在畫板上畫矩形,起始座標爲(10,10),寬爲,高爲
g.DrawEllipse(p, 10, 10, 100, 100);//在畫板上畫橢圓,起始座標爲(10,10),外接矩形的寬爲,高爲
}
1.3Brush類的使用
做用:咱們能夠用畫刷填充各類圖形形狀,如矩形、橢圓、扇形、多邊形和封閉路徑等,主要有幾種不一樣類型的畫刷:
SolidBrush:畫刷最簡單的形式,用純色進行繪製
• HatchBrush:相似於 SolidBrush,可是能夠利用該類從大量預設的圖案中選擇繪製時要使用的圖案,而不是純色
• TextureBrush:使用紋理(如圖像)進行繪製
• LinearGradientBrush:使用沿漸變混合的兩種顏色進行繪製
• PathGradientBrush :基於編程者定義的惟一路徑,使用複雜的混合色漸變進行繪製
如下是一段實例的代碼
Graphics g = this.CreateGraphics(); Rectangle rect = new Rectangle(10, 10, 50, 50);//定義矩形,參數爲起點橫縱座標以及其長和寬 //單色填充 SolidBrush b1 = new SolidBrush(Color.Blue);//定義單色畫刷 g.FillRectangle(b1, rect);//填充這個矩形 //字符串 g.DrawString("字符串", new Font("宋體", 10), b1, new PointF(90, 10)); //用圖片填充 TextureBrush b2 = new TextureBrush(Image.FromFile(@"e:\picture\1.jpg")); rect.Location = new Point(10, 70);//更改這個矩形的起點座標 rect.Width = 200;//更改這個矩形的寬來 rect.Height = 200;//更改這個矩形的高 g.FillRectangle(b2, rect); //用漸變色填充 rect.Location = new Point(10, 290); LinearGradientBrush b3 = new LinearGradientBrush(rect, Color.Yellow , Color.Black , LinearGradientMode.Horizontal); g.FillRectangle(b3, rect);
2、其餘知識點
2.1座標軸的轉化
在winform中的座標軸和咱們平時接觸的平面直角座標軸不一樣,winform中的座標軸方向徹底相反:窗體的左上角爲原點(0,0),水平向左則X增大,垂直下向則Y增大
Graphics g = this.CreateGraphics(); //單色填充 //SolidBrush b1 = new SolidBrush(Color.Blue);//定義單色畫刷 Pen p = new Pen(Color.Blue,1); //轉變座標軸角度 for (int i = 0; i < 90; i++) { g.RotateTransform(i);//每旋轉一度就畫一條線 g.DrawLine(p, 0, 0, 100, 0); g.ResetTransform();//恢復座標軸座標 } //平移座標軸 g.TranslateTransform(100, 100); g.DrawLine(p, 0, 0, 100, 0); g.ResetTransform(); //先平移到指定座標,而後進行度旋轉 g.TranslateTransform(100,200); for (int i = 0; i < 8; i++) { g.RotateTransform(45); g.DrawLine(p, 0, 0, 100, 0); } g.Dispose();
2.2附加一段仿QQ截圖形式的一種截圖形式
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(); } #region 用戶變量 private Point DownPoint = Point.Empty;//記錄鼠標按下座標,用來肯定繪圖起點 private bool CatchFinished = false;//用來表示是否截圖完成 private bool CatchStart = false;//表示截圖開始 private Bitmap originBmp;//用來保存原始圖像 private Rectangle CatchRect;//用來保存截圖的矩形 #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) {//若是捕捉開始 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();//從新顯示窗體 } } }