C# GDI+绘图介绍
最近查閱網上資料,將GDI+的基本知識匯總如下:
一、基本的知識
GDI+:Graphics Device Interface Plus也就是圖形設備接口,提供了各種豐富的圖形圖像處理功能;
在C#.NET中,使用GDI+處理二維(2D)的圖形和圖像,使用DirectX處理三維(3D)的圖形圖像,
圖形圖像處理用到的主要命名空間是System.Drawing,程序集:System.Drawing.d11:提供了對GDI+基本圖形功能的訪問,主要有Graphics類、Bitmap類、從Brush類繼承的類、Font類、Icon類、Image類、Pen類、Color類等.
1.1Graphics類
俗稱:畫布,用于在其上面繪制相應的圖像、圖片、文字等內容...有以下三種創建方式
(1)利用窗體或控件的Paint事件的參數PaintEventArgs創建Graphics對象。
? ? ? ? private?void?Form1_Paint(object?sender,?PaintEventArgs?e)
? ? ? ??{
? ? ? ? ? ? Graphics?g?=?e.Graphics;?//創建畫板,這里的畫板是由Form提供的.
? ? ? ? }
(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.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();//重新顯示窗體}}}
轉載于:https://www.cnblogs.com/liuxiaowei0543/p/3683976.html
總結
以上是生活随笔為你收集整理的C# GDI+绘图介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IIS解决 上传文件大小限制
- 下一篇: python元祖和文件用法举例