超全面的.NET GDI+圖形圖像編程教程
本篇主題內容是.NET GDI+圖形圖像編程系列的教程,不要被這個滾動條嚇到,為了查找方便,我沒有分開寫,上面加了目錄了,而且很多都是源碼和圖片~
GDI+繪圖基礎
編寫圖形程序時需要使用GDI(Graphics Device Interface,圖形設備接口)。
從程序設計的角度看,GDI包括兩部分:GDI對象和GDI函數。GDI對象定義了GDI函數使用的工具和環境變量;而GDI函數使用GDI對象繪制各種圖形。
在C#中,進行圖形程序編寫時用到的是GDI+(Graphics Device Interface Plus,圖形設備接口)版本,GDI+是GDI的進一步擴展,它使我們編程更加方便。
1 GDI+概述
GDI+是微軟在Windows 2000以后操作系統中提供的新的圖形設備接口,其通過一套部署為托管代碼的類來實現,這套類被稱為GDI+的“托管類接口”。
GDI+主要提供了一下三類服務:
1.二維矢量圖形:GDI+提供了存儲圖形基元自身信息的類(或結構體)、存儲圖形基元繪制方式信息的類以及實際進行繪制的類。
2.圖像處理:大多數圖片都難以劃定為直線和曲線的集合,無法使用二維矢量圖形方式進行處理。因此,GDI+為我們提供了Bitmap、Image等類,它們可用于顯示、操作和奧村BMP、JPG、GIF等圖像格式。
3.文字顯示:GDI+支持使用各種字體、字號和樣式來顯示文本。
我們要進行圖形編程,就必須先講解Graphics類,同時我們還必須掌握Pen、Brush和Rectangle這幾種類。
GDI+比GDI優越主要表現在兩個方面:
1.GDI+通過提供新功能(例如:漸變畫筆和Alpha混合)擴展了GDI的功能;
2.修訂了編程模型,是圖形編程更加簡易靈活。
2 Graphics類
Graphics類封裝一個GDI+繪圖圖面,提供將對象繪制到現實設備的方法,Graphics與特定的設備上下文關聯。
畫圖方法都被包括在Graphics類中國,在畫任何對象(例如:Circle Rectangle)時,我們首先要創建一個Graphics類實例,這個實例相當于建立了一塊畫布,有了畫布才可以用各種畫圖方法進行繪圖。
繪圖程序的設計過程一般分為兩個步驟:1.創建Graphics;2.使用Graphics對象的方法繪圖、顯示文本或處理圖像。
通常我們使用下述三種方法來創建一個Graphics對象:
方法一:利用控件或窗體的Paint事件中的PaintEventArgs
在窗體或控件的Paint事件中接受對圖形對象的引用,作為PaintEventArgs(PaintEventArgs指定繪制控件所用的Graphics)的一部分,在為控件創建繪制代碼時,通常會使用此方法來獲取對圖形對象的引用。例如:
// 窗體的Paint事件的響應方法 private void Frm_Demo_Paint(object sender, PaintEventArgs e) { Graphics _Graphics = e.Graphics; }// 也可以直接重載控件或窗體的OnPaint方法 protected override void OnPaint(PaintEventArgs e) { Graphics _Graphics = e.Graphics; }</pre>
Paint事件在重繪控件時發生。
方法二:調用某控件或窗體的CreateGraphics方法
調用某控件或窗體的CreateGraphics方法以獲取對Graphics對象的引用,該對象表示該控件或窗體的繪圖圖面。
如果想在已存在的窗體或控件上繪圖,通常會使用此方法,例如:
- 1 Graphics _Graphics = this.CreateGraphics(); // 在當前窗體上創建Graphics對象
方法三:調用Graphics類的FromImage靜態方法
由從Image集成的任何對象創建Graphics對象。在需要更改已存在的圖像時,通常會使用此方法。例如:
使用Graphics.FromImage()方法 創建Graphics對象
- Image img = Image.FromFile(“孤影.jpg”); // 建立Image對象
- Graphics _Graphics = Graphics.FromImage(img); // 創建Graphics對象
2.1 Graphics類的方法成員
有了一個Graphics的對象引用后,就可以利用該對象的成員進行各種各樣圖形的繪制,下面表格列出了Graphics類的常用方法成員:
名稱 | 說明 | 名稱 | 說明 |
DrawArc | 畫弧 | DrawBezier | 畫立體的貝爾塞曲線 |
DrawBeziers | 畫連續立體的貝爾塞曲線 | DrawClosedCurve | 畫閉合曲線 |
DrawCurve | 畫曲線 | DrawEllipse | 畫橢圓 |
DrawImage | 畫圖像 | DrawLine | 畫線 |
DrawPath | 通過路徑畫線和曲線 | DrawPie | 畫餅形 |
DrawPolygon | 畫多邊形 | DrawRectangle | 畫矩形 |
DrawString | 繪制文字 | FillEllipse | 填充橢圓 |
FillPath | 填充路徑 | FillPie | 填充餅圖 |
FillPolygon | 填充多邊形 | FillRectangle | 填充矩形 |
FillRectangles | 填充矩形組 | FillRegion | 填充區域 |
在.NET中,GDI+的所有繪圖功能都包括在System、System.Drawimg、System.Drawimg.Imaging、 System.Drawimg.Drawimg2D和System.Drawimg.Text等命名空間中,因此開始用GDI+類之前,需要先引用相應的 命名空間。
2.2 引用命名空間
在C#應用程序中使用using命令引用給定的命名空間或類,下面是一個C#應用程序引用命名空間的例子:
using System; using System.Collections.Generic; using System.Data; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging;
3 常用畫圖對象
在創建了Graphics對象后,就可以用它開始繪圖了,可以畫線、填充圖形、顯示文本等等,其中主要用到的對象還有:
Pen:用來用patterns、colors或者bitmaps進行填充
Color:用來畫線和多邊形,包括矩形、圓和餅形
Font:用來給文字設置字體格式
Brush:用來描述顏色
Rectangle:矩形結構通常用來在窗體上畫矩形
Point:描述一對有序的x,y兩個坐標值
3.1 Pen類
Pen類用來繪制指定寬度和樣式的直線。使用DashStyle屬性繪制幾種虛線,可以使用各種各樣填充樣式(包括純色和紋理)來填充Pen繪制的直線,填充模式取決于畫筆或用作填充對象的紋理。
使用畫筆時,需要先實例化一個畫筆對象,主要有以下幾種方法:
// 用指定的顏色實例化一只畫筆 public Pen(Color);// 用指定的畫刷實例化一只畫筆 public Pen(Brush);
// 用指定的畫刷和寬度實例化一只畫筆 public Pen(Brush, float);
// 用指定的顏色和寬度實例化一只畫筆 public Pen(Color, float);
// 實例化畫筆格式如下: Pen pen = new Pen(Color.Blue); // 或者: Pen pen = new Pen(Color.Blue, 100);</pre>
Pen常用的屬性如下:
名稱 | 說明 | 名稱 | 說明 |
Alignment | 獲得或者設置畫筆的對齊方式 | Brush | 獲得或者設置畫筆的屬性 |
Color | 獲得或者設置畫筆的顏色 | Width | 獲得或者設置畫筆的寬度 |
3.2 Color結構
在自然界中,顏色大都由透明度(A)和三基色(R,G,B)所組成。在GDI+中,通過Color結構封裝對顏色的定義,Color結構中,除了提供(A,R,G,B)以外,還提供許多系統定義的顏色,如Pink(粉色)。另外,還提供許多靜態成員,用戶對顏色進行操作。
Color結構的基本屬性如下表:
名稱 | 說明 |
A | 獲取此Color結構的Alpha分量值,取值(0~255) |
R | 獲取此Color結構的紅色分量值,取值(0~255) |
G | 獲取此Color結構的綠色分量值,取值(0~255) |
B | 獲取此Color結構的藍色分量值,取值(0~255) |
Name | 獲取此Color結構的名稱,這將返回用戶定義的顏色的名稱或已知顏色的名稱(如果該顏色是從某個名稱創建的)。對于自定義的顏色,這將返回RGB值。 |
Color結構的基本(靜態)方法如下表:
名稱 | 說明 |
FromArgb | 從四個8位的ARGB分量(Alpha、紅色、綠色和藍色)值創建Color結構 |
FromKnowColor | 從指定餓預定義顏色創建一個Color結構 |
FromName | 從預定義顏色的指定名稱創建一個Color結構。 |
Color結構變量可以通過已有顏色構造,也可以通過RGB建立,例如:
創建Color構造對象
Color color1 = Color.FromArgb(96, 06, 25); Color color2 = Color.FromKnownColor(KnownColor.Blue); // KnowColor為枚舉類型 Color color3 = Color.FromName("LightBlue");
在圖像處理中一般需要獲取或設置像素的顏色值,獲取一幅圖像的某個像素顏色值得具體步驟如下:
1.定義Bitmap
Bitmap bitmap = new Bitmap("D:\\孤影\\LonelyShadow.bmp");
2.定義一個顏色變量,把在指定位置所取得的像素值存入顏色變量中
Color color = new Color(); color = bitmap.GetPixel(10, 10); // 獲取此Bitmap中指定像素的顏色
3.將顏色值分解出單色分量值
int r, g, b; r = color.R; g = color.G; b = color.B;
3.3 Font類
Font類定義特定文本格式,包括字體、字號和字形屬性。Font類的常用構造函數是:
public Font(string 字體名, float 字號, FontStyle 字形){} 其中字號和字體為可選項
public Font(string 字體名, float 字號) 其中字體名為Font的FontFamily的字符串表示形式
下面是定義一個F哦你團隊相愛難過的示例代碼:
FontFamily fontFamily = new FontFamily("Arial"); Font font = new Font(fontFamily, 16, FontStyle.Regular, GraphicsUnit.Pixel);
字體常用屬性如下表:
名稱 | 說明 | 名稱 | 說明 |
Bold | 是否為粗體 | FontFamily | 字體成員 |
Height | 字體高 | Italic | 是否為斜體 |
Name | 字體名稱 | Size | 字體尺寸 |
SizeInPoints | 獲取此Font對象的字號,以磅為單位 | Strikeout | 是否有刪除線 |
Style | 字體類型 | Underline | Unit |
Unit | 字體尺寸單位 |
3.4 Brush類
Brush類是一個抽象的基類,因此它不能被實例化,我們總是用它的派生類進行實例化一個畫刷的對象,當我們對圖形內部進行填充操作時就會用到畫刷,關于畫刷在 [1.5] 中有詳細的講解。
3.5 Rectangle結構
存儲一組整數,共四個,表示一個矩形的位置和大小。
矩形結構通常用來在窗體上畫矩形,除了利用它的構造函數矩形對象外,還可以利用Rectangle結構的屬性成員,其屬性成員如下表:
名稱 | 說明 | 名稱 | 索命 |
Bottom | 底端坐標 | Height | 矩形高 |
IsEmpty | 測試矩形寬和高是否為0 | Left | 矩形左邊坐標 |
Location | 矩形的位置 | Right | 矩形右邊坐標 |
Size | 矩形尺寸 | Top | 矩形頂端坐標 |
Width | 矩形寬 | X | 矩形左上角頂點X坐標 |
Y | 矩形左上角頂點Y坐標 |
Rectangle結構的構造函數有以下兩個:
Rectangle結構的構造函數
// 用指定的位置和大小初始化Rectangle類的新實例 public Rectangle(Point, Size); // Size結構存儲一個有序整數對,通常為矩形的寬度和高度 public Rectangle(int, int, int, int);
1.3.6 Point結構
用指定坐標初始化Point類的新實例,這個結構很像C++的Point結構,它描述了一對有序的x,y兩個坐標值,其構造函數為:
public Point(int x, int y); 其中x為該點的水平位置;y為該點的垂直位置。
下面是構造Point對象的示例代碼:
Point pt1 = new Point(30, 30); Point pt2 = new Point(110, 110);
4 基本圖形繪制舉例
4.1 畫一個矩形
建一個C#.NET WinForms窗體應用程序,通過在窗體的OnPaint事件中繪制一個填充的漸變矩形:
填充矩形方法FillRectangle()的語法幫助定義如下:
// // 摘要: // 填充 System.Drawing.Rectangle 結構指定的矩形的內部。 // // 參數: // brush: // 確定填充特性的 System.Drawing.Brush。 // // rect: // System.Drawing.Rectangle 結構,它表示要填充的矩形。 // // 異常: // System.ArgumentNullException: // brush 為 null。 public void FillRectangle(Brush brush, Rectangle rect); // // 摘要: // 填充 System.Drawing.RectangleF 結構指定的矩形的內部。 // // 參數: // brush: // 確定填充特性的 System.Drawing.Brush。 // // rect: // System.Drawing.RectangleF 結構,它表示要填充的矩形。 // // 異常: // System.ArgumentNullException: // brush 為 null。 public void FillRectangle(Brush brush, RectangleF rect); // // 摘要: // 填充由一對坐標、一個寬度和一個高度指定的矩形的內部。 // // 參數: // brush: // 確定填充特性的 System.Drawing.Brush。 // // x: // 要填充的矩形的左上角的 x 坐標。 // // y: // 要填充的矩形的左上角的 y 坐標。 // // width: // 要填充的矩形的寬度。 // // height: // 要填充的矩形的高度。 // // 異常: // System.ArgumentNullException: // brush 為 null。 public void FillRectangle(Brush brush, float x, float y, float width, float height); // // 摘要: // 填充由一對坐標、一個寬度和一個高度指定的矩形的內部。 // // 參數: // brush: // 確定填充特性的 System.Drawing.Brush。 // // x: // 要填充的矩形的左上角的 x 坐標。 // // y: // 要填充的矩形的左上角的 y 坐標。 // // width: // 要填充的矩形的寬度。 // // height: // 要填充的矩形的高度。 // // 異常: // System.ArgumentNullException: // brush 為 null。 public void FillRectangle(Brush brush, int x, int y, int width, int height);
我們在這里只使用第一種定義,演示填充矩形,示例代碼如下:
/// <summary> /// 窗體的Paint事件的響應方法 /// </summary> /// <param name="sender">當前事件觸發者(當前窗體)</param> /// <param name="e">附帶的事件參數</param> private void Frm_Demo_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; // 創建當前窗體的Graphics對象 Rectangle rect = new Rectangle(50, 30, 100, 100); // 創建一個矩形(x,y,width,height) // 創建線性漸變畫刷(畫刷界限, 起始顏色, 結束顏色, 漸變角度) LinearGradientBrush lBrush = new LinearGradientBrush(rect, Color.Purple, Color.LightBlue, LinearGradientMode.BackwardDiagonal); g.FillRectangle(lBrush, rect); // 走起~ }
上述代碼運行效果如下:
4.2 畫一個弧
畫弧線的語法定義如下:
// // 摘要: // 繪制一段弧線,它表示 System.Drawing.Rectangle 結構指定的橢圓的一部分。 // // 參數: // pen: // System.Drawing.Pen,它確定弧線的顏色、寬度和樣式。 // // rect: // System.Drawing.RectangleF 結構,它定義橢圓的邊界。 // // startAngle: // 從 x 軸到弧線的起始點沿順時針方向度量的角(以度為單位)。 // // sweepAngle: // 從 startAngle 參數到弧線的結束點沿順時針方向度量的角(以度為單位)。 // // 異常: // System.ArgumentNullException: // pen 為 null。 public void DrawArc(Pen pen, Rectangle rect, float startAngle, float sweepAngle);
參照定義的幫助,可寫出如下畫弧線的代碼:
/// <summary> /// 窗體的Paint事件的響應方法 /// </summary> /// <param name="sender">當前事件觸發者(當前窗體)</param> /// <param name="e">附帶的事件參數</param> private void Frm_Demo_Paint(object sender, PaintEventArgs e) { Graphics graphics = e.Graphics; Pen pen = new Pen(Color.Blue); Rectangle rect = new Rectangle(50,50,200,100); graphics.DrawArc(pen, rect, 12, 84); }
上述代碼運行結果如下:
4.3 畫線
畫線DrawLine()方法的語法定義如下:
// // 摘要: // 繪制一條連接兩個 System.Drawing.Point 結構的線。 // // 參數: // pen: // System.Drawing.Pen,它確定線條的顏色、寬度和樣式。 // // pt1: // System.Drawing.Point 結構,它表示要連接的第一個點。 // // pt2: // System.Drawing.Point 結構,它表示要連接的第二個點。 // // 異常: // System.ArgumentNullException: // pen 為 null。 public void DrawLine(Pen pen, Point pt1, Point pt2); // // 摘要: // 繪制一條連接兩個 System.Drawing.PointF 結構的線。 // // 參數: // pen: // System.Drawing.Pen,它確定線條的顏色、寬度和樣式。 // // pt1: // System.Drawing.PointF 結構,它表示要連接的第一個點。 // // pt2: // System.Drawing.PointF 結構,它表示要連接的第二個點。 // // 異常: // System.ArgumentNullException: // pen 為 null。 public void DrawLine(Pen pen, PointF pt1, PointF pt2); // // 摘要: // 繪制一條連接由坐標對指定的兩個點的線條。 // // 參數: // pen: // System.Drawing.Pen,它確定線條的顏色、寬度和樣式。 // // x1: // 第一個點的 x 坐標。 // // y1: // 第一個點的 y 坐標。 // // x2: // 第二個點的 x 坐標。 // // y2: // 第二個點的 y 坐標。 // // 異常: // System.ArgumentNullException: // pen 為 null。 public void DrawLine(Pen pen, float x1, float y1, float x2, float y2); // // 摘要: // 繪制一條連接由坐標對指定的兩個點的線條。 // // 參數: // pen: // System.Drawing.Pen,它確定線條的顏色、寬度和樣式。 // // x1: // 第一個點的 x 坐標。 // // y1: // 第一個點的 y 坐標。 // // x2: // 第二個點的 x 坐標。 // // y2: // 第二個點的 y 坐標。 // // 異常: // System.ArgumentNullException: // pen 為 null。 public void DrawLine(Pen pen, int x1, int y1, int x2, int y2);
根據定義的幫助,我們以第一種語法 可以寫出如下示例代碼:
/// <summary> /// 窗體的Paint事件的響應方法 /// </summary> /// <param name="sender">當前事件觸發者(當前窗體)</param> /// <param name="e">附帶的事件參數</param> private void Frm_Demo_Paint(object sender, PaintEventArgs e) { Graphics graphics = e.Graphics; // 創建當前窗體的Graphics對象 Pen pen = new Pen(Color.Blue); // 創建藍色畫筆對象 Point pointStart = new Point(30, 30); // 創建起始點 Point pointEnd = new Point(150, 150); // 創建結束點 graphics.DrawLine(pen, pointStart, pointEnd); // 畫線 }
上述代碼運行效果圖如下:
4.4 畫橢圓
還是先看一下DrawEllipse()畫橢圓的語法定義:
// // 摘要: // 繪制邊界 System.Drawing.Rectangle 結構指定的橢圓。 // // 參數: // pen: // System.Drawing.Pen,它確定曲線的顏色、寬度和樣式。 // // rect: // System.Drawing.Rectangle 結構,它定義橢圓的邊界。 // // 異常: // System.ArgumentNullException: // pen 為 null。 public void DrawEllipse(Pen pen, Rectangle rect); // // 摘要: // 繪制邊界 System.Drawing.RectangleF 定義的橢圓。 // // 參數: // pen: // System.Drawing.Pen,它確定曲線的顏色、寬度和樣式。 // // rect: // System.Drawing.RectangleF 結構,它定義橢圓的邊界。 // // 異常: // System.ArgumentNullException: // pen 為 null。 public void DrawEllipse(Pen pen, RectangleF rect); // // 摘要: // 繪制一個由邊框(該邊框由一對坐標、高度和寬度指定)定義的橢圓。 // // 參數: // pen: // System.Drawing.Pen,它確定曲線的顏色、寬度和樣式。 // // x: // 定義橢圓的邊框的左上角的 X 坐標。 // // y: // 定義橢圓的邊框的左上角的 Y 坐標。 // // width: // 定義橢圓的邊框的寬度。 // // height: // 定義橢圓的邊框的高度。 // // 異常: // System.ArgumentNullException: // pen 為 null。 public void DrawEllipse(Pen pen, float x, float y, float width, float height); // // 摘要: // 繪制一個由邊框定義的橢圓,該邊框由矩形的左上角坐標、高度和寬度指定。 // // 參數: // pen: // System.Drawing.Pen,它確定曲線的顏色、寬度和樣式。 // // x: // 定義橢圓的邊框的左上角的 X 坐標。 // // y: // 定義橢圓的邊框的左上角的 Y 坐標。 // // width: // 定義橢圓的邊框的寬度。 // // height: // 定義橢圓的邊框的高度。 // // 異常: // System.ArgumentNullException: // pen 為 null。 public void DrawEllipse(Pen pen, int x, int y, int width, int height);
參照上面的語法定義,我們根據第一種語法,可以寫出如下示例代碼:
/// <summary> /// 窗體的Paint事件的響應方法 /// </summary> /// <param name="sender">當前事件觸發者(當前窗體)</param> /// <param name="e">附帶的事件參數</param> private void Frm_Demo_Paint(object sender, PaintEventArgs e) { Graphics graphics = e.Graphics; // 創建當前窗體的Graphics對象 Pen pen = new Pen(Color.Blue, 100); // 創建藍色 粗細為100的畫筆對象 Rectangle rect = new Rectangle(50, 50, 200, 100); // 創建橢圓所在的矩形范圍 graphics.DrawEllipse(pen, rect); // 在指定的范圍內畫橢圓 }
上述代碼運行結果如下:
4.5 輸出文本
輸出文本用到的是Graphics對象的DrawString()方法,語法定義如下:
// // 摘要: // 在指定位置并且用指定的 System.Drawing.Brush 和 System.Drawing.Font 對象繪制指定的文本字符串。 // // 參數: // s: // 要繪制的字符串。 // // font: // System.Drawing.Font,它定義字符串的文本格式。 // // brush: // System.Drawing.Brush,它確定所繪制文本的顏色和紋理。 // // point: // System.Drawing.PointF 結構,它指定所繪制文本的左上角。 // // 異常: // System.ArgumentNullException: // brush 為 null。 - 或 - s 為 null。 public void DrawString(string s, Font font, Brush brush, PointF point); // // 摘要: // 在指定矩形并且用指定的 System.Drawing.Brush 和 System.Drawing.Font 對象繪制指定的文本字符串。 // // 參數: // s: // 要繪制的字符串。 // // font: // System.Drawing.Font,它定義字符串的文本格式。 // // brush: // System.Drawing.Brush,它確定所繪制文本的顏色和紋理。 // // layoutRectangle: // System.Drawing.RectangleF 結構,它指定所繪制文本的位置。 // // 異常: // System.ArgumentNullException: // brush 為 null。 - 或 - s 為 null。 public void DrawString(string s, Font font, Brush brush, RectangleF layoutRectangle); // // 摘要: // 在指定位置并且用指定的 System.Drawing.Brush 和 System.Drawing.Font 對象繪制指定的文本字符串。 // // 參數: // s: // 要繪制的字符串。 // // font: // System.Drawing.Font,它定義字符串的文本格式。 // // brush: // System.Drawing.Brush,它確定所繪制文本的顏色和紋理。 // // x: // 所繪制文本的左上角的 x 坐標。 // // y: // 所繪制文本的左上角的 y 坐標。 // // 異常: // System.ArgumentNullException: // brush 為 null。 - 或 - s 為 null。 public void DrawString(string s, Font font, Brush brush, float x, float y); // // 摘要: // 使用指定 System.Drawing.StringFormat 的格式化特性,用指定的 System.Drawing.Brush 和 System.Drawing.Font // 對象在指定的位置繪制指定的文本字符串。 // // 參數: // s: // 要繪制的字符串。 // // font: // System.Drawing.Font,它定義字符串的文本格式。 // // brush: // System.Drawing.Brush,它確定所繪制文本的顏色和紋理。 // // point: // System.Drawing.PointF 結構,它指定所繪制文本的左上角。 // // format: // System.Drawing.StringFormat,它指定應用于所繪制文本的格式化特性(如行距和對齊方式)。 // // 異常: // System.ArgumentNullException: // brush 為 null。 - 或 - s 為 null。 public void DrawString(string s, Font font, Brush brush, PointF point, StringFormat format); // // 摘要: // 使用指定 System.Drawing.StringFormat 的格式化特性,用指定的 System.Drawing.Brush 和 System.Drawing.Font // 對象在指定的矩形繪制指定的文本字符串。 // // 參數: // s: // 要繪制的字符串。 // // font: // System.Drawing.Font,它定義字符串的文本格式。 // // brush: // System.Drawing.Brush,它確定所繪制文本的顏色和紋理。 // // layoutRectangle: // System.Drawing.RectangleF 結構,它指定所繪制文本的位置。 // // format: // System.Drawing.StringFormat,它指定應用于所繪制文本的格式化特性(如行距和對齊方式)。 // // 異常: // System.ArgumentNullException: // brush 為 null。 - 或 - s 為 null。 public void DrawString(string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format); // // 摘要: // 使用指定 System.Drawing.StringFormat 的格式化特性,用指定的 System.Drawing.Brush 和 System.Drawing.Font // 對象在指定的位置繪制指定的文本字符串。 // // 參數: // s: // 要繪制的字符串。 // // font: // System.Drawing.Font,它定義字符串的文本格式。 // // brush: // System.Drawing.Brush,它確定所繪制文本的顏色和紋理。 // // x: // 所繪制文本的左上角的 x 坐標。 // // y: // 所繪制文本的左上角的 y 坐標。 // // format: // System.Drawing.StringFormat,它指定應用于所繪制文本的格式化特性(如行距和對齊方式)。 // // 異常: // System.ArgumentNullException: // brush 為 null。 - 或 - s 為 null。 public void DrawString(string s, Font font, Brush brush, float x, float y, StringFormat format);
根據上述定義,我們以 public void DrawString(string s, Font font, Brush brush, float x,float y); 語法可以寫出如下示例代碼:
/// <summary> /// 窗體的Paint事件的響應方法 /// </summary> /// <param name="sender">當前事件觸發者(當前窗體)</param> /// <param name="e">附帶的事件參數</param> private void Frm_Demo_Paint(object sender, PaintEventArgs e) { Font font = new Font("華文行楷", 40); // 創建Font字體對象 Graphics graphics = e.Graphics; // 創建當前窗體的Graphics對象 graphics.DrawString("孤影'Blog 歡迎您!", font, new SolidBrush(Color.Black), 30, 60); }
上述代碼運行結果如下:
4.6 填充路徑
填充路徑的語法定義如下:
// // 摘要: // 填充 System.Drawing.Drawing2D.GraphicsPath 的內部。 // // 參數: // brush: // 確定填充特性的 System.Drawing.Brush。 // // path: // System.Drawing.Drawing2D.GraphicsPath,它表示要填充的路徑。 // // 異常: // System.ArgumentNullException: // brush 為 null。 - 或 - path 為 null。 public void FillPath(Brush brush, GraphicsPath path);
根據上述語法定義,可寫出如下示例代碼:
/// <summary> /// 窗體的Paint事件的響應方法 /// </summary> /// <param name="sender">當前事件觸發者(當前窗體)</param> /// <param name="e">附帶的事件參數</param> private void Frm_Demo_Paint(object sender, PaintEventArgs e) { Graphics graphics = e.Graphics; // 創建當前窗體的Graphics對象 graphics.FillRectangle(new SolidBrush(Color.White), this.ClientRectangle); // 以白色畫刷填充當前窗體 // 創建線組 GraphicsPath path = new GraphicsPath(new Point[] { new Point(40,140), new Point(275,200), new Point(105,225), new Point(190,300), new Point(50,350), new Point(20,180) }, new byte[] { (byte)PathPointType.Start, (byte)PathPointType.Bezier, (byte)PathPointType.Bezier, (byte)PathPointType.Bezier, (byte)PathPointType.Line, (byte)PathPointType.Line }); // 路徑筆刷 PathGradientBrush pathGradientBrush = new PathGradientBrush(path); // 設置路徑中的點對應的顏色數組 pathGradientBrush.SurroundColors = new Color[] { Color.Green, Color.Yellow, Color.Red, Color.Blue, Color.Orange, Color.White }; graphics.FillPath(pathGradientBrush, path); // 填充路徑 }
上述代碼運行結果如下:
注意:GraphicsPath類位于命名空間“System.Drawimg.Drawimg2D”中,表示一系列相互連接的直線和曲線。
5 畫刷和畫刷類型
Brush類型是一個抽象類,所以它不能被實例化,也就是不能直接應用,但是我們可以利用他的派生類,如:HatchBrush、SolidBrush和TextureBrush等。
畫刷類型一般在“System.Drawing”命名空間中,如果應用HatchBrush和GradientBrush畫刷,需要在程序中引入“System.Drawing2D”命名空間。
5.1 SolidBrush(單色畫刷)
它是一種一般的畫刷,通常只用一種顏色去填充GDI+圖形,例如如下示例代碼:
/// <summary> /// 窗體的Paint事件的響應方法 /// </summary> /// <param name="sender">當前事件觸發者(當前窗體)</param> /// <param name="e">附帶的事件參數</param> private void Frm_Demo_Paint(object sender, PaintEventArgs e) { Graphics graphics = e.Graphics; // 創建當前窗體的Graphics對象 SolidBrush solidBrushR = new SolidBrush(Color.Red); // 紅色畫刷 SolidBrush solidBrushG = new SolidBrush(Color.Green); // 綠色畫刷 SolidBrush solidBrushB = new SolidBrush(Color.Blue); // 藍色畫刷graphics.FillEllipse(solidBrushG, 20, 40, 60, 70); // 用綠色畫刷填充一個橢圓
Rectangle rect = new Rectangle(0, 0, 200, 100); // 矩形 graphics.FillPie(solidBrushB, 0, 0, 200, 40, 0.0f, 30.0f); // 填充餅圖
// 組成多邊形的點 PointF point1 = new PointF(50.0f, 250.0f); PointF point2 = new PointF(100.0f, 25.0f); PointF point3 = new PointF(150.0f, 40.0f); PointF point4 = new PointF(200.0f, 50.0f); PointF point5 = new PointF(250.0f, 100.0f); PointF[] curvePoints = { point1, point2, point3, point4, point5 }; graphics.FillPolygon(solidBrushR, curvePoints); // 填充多邊形 }</pre>
運行效果如下:
5.2 HatchBrush(陰影畫刷)
HatchBrush類位于“System.Drawing.Drawing2D”命名空間中。陰影畫刷有兩種顏色:前景色和背景色,以及6種陰影。前景色定義線條的顏色,背景色定義線條之間間隙的顏色。
HatchBrush類有兩個構造函數:
1.public HatchBrush(HatchStyle, Color foreColor);
2.public HatchBrush(HatchStyle, Color foreColor, Color backColor);
HatchStyle枚舉值指定可用于HatchBrush對象的不同圖案,主要成員如下:
名稱 | 說明 | 名稱 | 說明 |
BackwardDiagonal | 從右上到左下的對角線的線條圖案 | Cross | 指定交叉的水平線和垂直線 |
DarkDownwardDiagonal | 指定從頂點到底點向右傾斜的對角線,其兩邊夾角比ForwardDiagonal小50%,寬度是其兩倍。此陰影圖案不是鋸齒消除的 | DarkHorizontal | 指定水平線的兩邊夾角比Horizontal小50%,并且寬度是Horizontal的兩倍 |
DarkUpwardDiagonal | 指定從頂點到底點向左傾斜的對角線,其兩邊夾角比BackwardDiagonal小50%,寬度是其兩倍,但這些直線不是鋸齒消除的 | DarkVertical | 指定垂直線的兩邊夾角比Vertical小50%,并且寬度是其兩倍 |
DashedDownwardDiagonal | 指定虛線對角線,這些對角線從頂點到底點向右傾斜 | DashedHorizontal | 指定虛線水平線 |
DashedUpwardDiagonal | 指定虛線對角線,這些對角線從頂點到底點向左傾斜 | DashedVertical | 指定虛線垂直線 |
DiagonalBrick | 指定具有分層磚塊外觀的陰影,它從頂點到底點向左傾斜 | DiagonalCross | 交叉對角線的圖案 |
Divot | 指定具有草皮層外觀的陰影 | ForwardDiagonal | 從坐上到右下分層磚塊外觀的陰影 |
Horizontal | 水平線的圖案 | HorizontalBrick | 指定具有水平分層磚塊外觀的陰影 |
LargeGrid | 指定陰影樣式Cross | LightHorizontal | 指定水平線,其兩邊夾角比Horizontal小50% |
LightVertical | 指定垂直線的兩邊夾角比Vertical小50% | Max | 指定陰影樣式SolidDiamond |
Min | 指定陰影樣式Horizontal | NarrowHorizontal | 指定水平線的兩邊夾角比陰影樣式Horizontal小75%(或者比LightHorizontal小25%) |
NarrowVertical | 指定垂直線的兩邊夾角比陰影樣式Vertical小75%(或者比LightVertical小25%) | OutlineDiamond | 指定互相交叉的正向對角線和反向對角線,但這些對角線不是鋸齒消除的 |
Percent05 | 指定5%陰影,前景色與背景色的比例為5:100 | Percent90 | 指定90%陰影,前景色與背景色的比例為90:100 |
Plaid | 指定具有格子花呢材料外觀的陰影 | Shingle | 指定帶有對角分層鵝卵石外觀的陰影,它從頂點到底點向右傾斜 |
SmallCheckerBoard | 指定帶有期盼外觀的陰影 | SmallDiamond | 指定具有對角放置的棋盤外觀的陰影 |
Sphere | 指定具有球體彼此相鄰放置的外觀的陰影 | Trellis | 指定具有格架外觀的陰影 |
Vertical | 垂直線的圖案 | Wave | 指定由代字號”~”構成的水平線 |
Weave | 指定具有織物外觀的陰影 |
我們隨便挑選三個樣式,如下示例代碼:
/// <summary> /// 窗體的Paint事件的響應方法 /// </summary> /// <param name="sender">當前事件觸發者(當前窗體)</param> /// <param name="e">附帶的事件參數</param> private void Frm_Demo_Paint(object sender, PaintEventArgs e) { Graphics graphics = e.Graphics; // 創建當前窗體的Graphics對象 // 創建用于畫三種不同樣式圖形的陰影畫筆 HatchBrush hatchBrushR = new HatchBrush(HatchStyle.DiagonalCross, Color.Chocolate, Color.Red); HatchBrush hatchBrushG = new HatchBrush(HatchStyle.DashedHorizontal, Color.Green, Color.Black); HatchBrush hatchBrushB = new HatchBrush(HatchStyle.Weave, Color.BlueViolet, Color.Blue);graphics.FillEllipse(hatchBrushR, 20, 80, 60, 20); // 填充橢圓
// 填充餅圖 Rectangle rect = new Rectangle(0, 0, 200, 100); graphics.FillPie(hatchBrushB, 0, 0, 200, 40, 0.0f, 30.0f);
// 填充自定義圖形 PointF point1 = new PointF(50.0f, 250.0f); PointF point2 = new PointF(100.0f, 25.0f); PointF point3 = new PointF(150.0f, 40.0f); PointF point4 = new PointF(250.0f, 50.0f); PointF point5 = new PointF(300.0f, 100.0f); PointF[] curvePoints = { point1, point2, point3, point4, point5 }; graphics.FillPolygon(hatchBrushG, curvePoints); }</pre>
上述代碼運行結果如下:
5.3 TextureBrush(紋理畫刷)
紋理畫刷擁有圖案,并且通常使用它來填充封閉的圖形。為了對它初始化,可以使用一個已經存在的別人設計好了的圖案,或使用常用的設計程序設計的自己 的圖案,同時應該使圖案存儲為常用圖形文件格式,如BMP格式文件,這有一個設計好的位圖:“LonelyShadow.bmp”文件,紋理畫刷使用的示 例代碼如下:
/// <summary> /// 窗體的Paint事件的響應方法 /// </summary> /// <param name="sender">當前事件觸發者(當前窗體)</param> /// <param name="e">附帶的事件參數</param> private void Frm_Demo_Paint(object sender, PaintEventArgs e) { Graphics graphics = e.Graphics; // 創建當前窗體的Graphics對象 Bitmap bitmap = new Bitmap("LonelyShadow.bmp"); // 根據文件創建原始大小的Bitmap對象 bitmap = new Bitmap(bitmap, this.ClientRectangle.Size); // 縮放到窗體大小 TextureBrush textureBrush = new TextureBrush(bitmap); graphics.FillEllipse(textureBrush, this.ClientRectangle); }上述代碼運行效果如下:
5.4 LinearGradientBrush 和 PathGradientBrush(漸變畫刷)
漸變畫刷類似于實心畫刷,因為他也是基于顏色的,與實心畫刷不同的是:漸變畫刷使用兩種顏色,它的主要特點是:在使用過程中,一種顏色在一段,而另外一種顏色在另一端,在中間,兩種顏色融合產生過度或衰減的效果。
漸變畫刷有兩種:線性畫刷和路徑畫刷(LinearGradientBrush 和 PathGradientBrush)。
其中LinearGradientBrush可以顯示線性漸變效果,而PathGradientBrush是路徑漸變的可以顯示比較具有彈性的漸變效果。
5.4.1 LinearGradientBrush類
LinearGradientBrush類構造函數如下:
public LinerGradientBrush(Point point1, Point point2, Color color1, Color color2)// point1: 表示線性漸變的起始點的Point結構
// point2: 表示線性漸變的終結點的Point結構
// color1: 表示線性漸變的起始顏色的Color結構
// color2: 表示線性漸變的結束顏色的Color結構</pre>
我們可以寫出如下示例代碼:
/// <summary> /// 窗體的Paint事件的響應方法 /// </summary> /// <param name="sender">當前事件觸發者(當前窗體)</param> /// <param name="e">附帶的事件參數</param> private void Frm_Demo_Paint(object sender, PaintEventArgs e) { Graphics graphics = e.Graphics; // 創建當前窗體的Graphics對象 LinearGradientBrush linearGradientBrush = new LinearGradientBrush(this.ClientRectangle, Color.White, Color.Blue, LinearGradientMode.Vertical); graphics.FillRectangle(linearGradientBrush, this.ClientRectangle); }上述代碼運行效果如下:
5.4.2 PathGradientBrush類
PathGradientBrush類的構造函數如下:public PathGradientBrush(GraphicsPath path); // path: GraphicsPath,定義此PathGradientBrush填充區域
PathGradientBrush使用的示例代碼如下:
/// <summary> /// 窗體的Paint事件的響應方法 /// </summary> /// <param name="sender">當前事件觸發者(當前窗體)</param> /// <param name="e">附帶的事件參數</param> private void Frm_Demo_Paint(object sender, PaintEventArgs e) { Graphics graphics = e.Graphics; // 創建當前窗體的Graphics對象 Point centerPoint = new Point(150, 100); int R = 60; GraphicsPath path = new GraphicsPath(); path.AddEllipse(centerPoint.X - R, centerPoint.Y - R, R * 2, R * 2); PathGradientBrush brush = new PathGradientBrush(path); brush.CenterPoint = centerPoint; // 指定路徑中心點 brush.CenterColor = Color.Red; // 指定路徑中心的顏色 brush.SurroundColors = new Color[] { Color.Plum }; graphics.FillEllipse(brush, centerPoint.X - R, centerPoint.Y - R, R * 2, R * 2); centerPoint = new Point(350, 100); R = 20; path = new GraphicsPath(); path.AddEllipse(centerPoint.X - R, centerPoint.Y - R, R * 2, R * 2); path.AddEllipse(centerPoint.X - R * 2, centerPoint.Y - R * 2, R * 4, R * 4); path.AddEllipse(centerPoint.X - R * 3, centerPoint.Y - R * 3, R * 6, R * 6); brush = new PathGradientBrush(path); brush.CenterPoint = centerPoint; brush.CenterColor = Color.Red; brush.SurroundColors = new Color[] { Color.Black, Color.Blue, Color.Green }; graphics.FillPath(brush, path); }上述代碼運行效果圖如下:
哈哈,看到這里,本篇的內容也就講完了,文章看似很長,其實內容主題也就是GDI+繪圖編程了,只是示例代碼多了一點點。
來自:孤影'Blog