超全面的.NET GDI+圖形圖像編程教程

jopen 10年前發布 | 56K 次閱讀 圖形 圖形/圖像處理

本篇主題內容是.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. 1 Graphics _Graphics = this.CreateGraphics();    // 在當前窗體上創建Graphics對象

方法三:調用Graphics類的FromImage靜態方法

由從Image集成的任何對象創建Graphics對象。在需要更改已存在的圖像時,通常會使用此方法。例如:

使用Graphics.FromImage()方法 創建Graphics對象

  1. Image img = Image.FromFile(“孤影.jpg”);   // 建立Image對象
  2. Graphics _Graphics = Graphics.FromImage(img);   // 創建Graphics對象

2.1 Graphics類的方法成員

有了一個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常用的屬性如下:

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結構的屬性成員,其屬性成員如下表:

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);  // 走起~
        }

上述代碼運行效果如下:

超全面的.NET GDI+圖形圖像編程教程

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);
        }

上述代碼運行結果如下:

超全面的.NET GDI+圖形圖像編程教程

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);   // 畫線
        }

上述代碼運行效果圖如下:

超全面的.NET GDI+圖形圖像編程教程

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);    // 在指定的范圍內畫橢圓
        }

上述代碼運行結果如下:

超全面的.NET GDI+圖形圖像編程教程

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);
        }

上述代碼運行結果如下:

超全面的.NET GDI+圖形圖像編程教程

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); // 填充路徑
        }

上述代碼運行結果如下:

超全面的.NET GDI+圖形圖像編程教程

注意: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>

運行效果如下:

超全面的.NET GDI+圖形圖像編程教程

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對象的不同圖案,主要成員如下:

HatchStyle枚舉圖案主要成員
名稱 說明 名稱 說明
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>

上述代碼運行結果如下:

超全面的.NET GDI+圖形圖像編程教程

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);
        }

上述代碼運行效果如下:

超全面的.NET GDI+圖形圖像編程教程

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);
        }

上述代碼運行效果如下:

超全面的.NET GDI+圖形圖像編程教程

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);
        }

上述代碼運行效果圖如下:

超全面的.NET GDI+圖形圖像編程教程

哈哈,看到這里,本篇的內容也就講完了,文章看似很長,其實內容主題也就是GDI+繪圖編程了,只是示例代碼多了一點點。

來自:孤影'Blog

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!