這篇文章主要為大家展示了“C#利用GDI+畫圖的示例分析”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“C#利用GDI+畫圖的示例分析”這篇文章吧。
目前創(chuàng)新互聯(lián)建站已為上千多家的企業(yè)提供了網(wǎng)站建設、域名、虛擬主機、成都網(wǎng)站托管、企業(yè)網(wǎng)站設計、渭濱網(wǎng)站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。前言
最近做一個微信公眾號服務,有一些簡單的圖片處理功能。主要就是用戶在頁面操作,前端做一些立刻顯示的效果,然后提交保存時后端真正修改原圖。
從程序設計的角度看,GDI包括兩部分:一部分是GDI對象,另一部分是GDI函數(shù)。GDI對象定義了GDI函數(shù)使用的工具和環(huán)境變量,而GDI函數(shù)使用GDI對象繪制各種圖形,在C#中,進行圖形程序編寫時用到的是GDI+(Graphics Device Interface Plus圖形設備接口)版本,GDI+是GDI的進一步擴展,它使我們編程更加方便。
C#中的GDI+就相當于java中的Swing控件,是編寫圖形界面必不可缺的一個接口。GDI+繪圖大的方便得益于C#的可視化編程,所有的控件只需要自己Drag,然后Place,最后Cilck添加監(jiān)聽方法。真的是too young too simple。
我們的后端是 ASP.NET,也就是 C# 語言了,C# 本身處理圖片還是比較方便的,使用 GDI+ 就好,只需要添加 System.Drawing 引用,不需要任何第三方庫。于是最近也用到一些比較常用的 GDI+ 圖片處理方法,就整理一下做個記錄了。
這個題目大概會寫幾篇文章,第一篇先簡單介紹一下 GDI+ 的常用對象,以及一些使用時候的注意事項,后面會挑一些項目中做過的比較有用的處理過程來介紹一下。
廢話不多說,開始進入正題。
需要用到的類
使用 GDI+ 畫圖會用到的幾個常用的類有:Graphics、Bitmap、Image。
其中 Graphics 是畫板。這個類包含了許多畫圖的方法,包括畫圖片(DrawImage),畫線(DrawLine),畫圓(DrawEllipse、FillEllipse),寫字(DrawString)等等。簡單說使用這個類可以完成我們需要的大部分工作。
生成一個 Graphics 對象需要用到 Image 或者 Bitmap。
PS: Winform 下可以直接從窗體或控件的事件中引用 Graphics 對象。
比如:
private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; // 創(chuàng)建畫板,這里的畫板是由Form提供的. }
不過本文討論的是其他場景,比如 ASP.NET MVC,或單純的控制臺程序。這些時候是沒有控件的,所以要用其他方法。
我一般用以下方法:
// // 摘要: // 從指定的 System.Drawing.Image 創(chuàng)建新的 System.Drawing.Graphics。 // // 參數(shù): // image: // 從中創(chuàng)建新 System.Drawing.Graphics 的 System.Drawing.Image。 // // 返回結果: // 此方法為指定的 System.Drawing.Image 返回一個新的 System.Drawing.Graphics。 // // 異常: // T:System.ArgumentNullException: // image 為 null。 // // T:System.Exception: // image 具有索引像素格式,或者格式未定義。 public static Graphics FromImage(Image image);
其中的參數(shù)可以傳入 Image 或 Bitmap,因為 Bitmap 是繼承自 Image 的。
如何創(chuàng)建畫板
如果是要對原圖進行處理,比如旋轉圖片,添加文字等,可以直接通過原圖片獲得畫板對象。
Image img = Image.FromFile(imgPath); Graphics graphics = Graphics.FromImage(img);
如果是要畫一個新的圖,可以通過要保存的圖片寬、高生成畫板。
Bitmap bmp = new Bitmap(width, height); Graphics graph = Graphics.FromImage(bmp);
PS: Graphics 本身是沒有提供構造函數(shù)來直接生成的。所以我們可以先創(chuàng)建一個需要保存圖片大小的 Bitmap 位圖對象,然后再獲得畫板對象。
如何保存畫好的圖片
通過調用 img.Save(savePath) 或者 bmp.Save(savePath) 即可保存對象。
PS: Bitmap 的 Save 方法是直接繼承自 Image 的。
GDI+ 的坐標系
GDI+ 的坐標系是個二維坐標系,不過又有點不一樣,它的原點是在左上角的。如下圖:
使用 GDI+ 的一些注意事項
這里我忍不住要先吐槽一下,GDI+ 的報錯信息不太友好啊。經(jīng)常只是返回一個“GDI+ 中發(fā)生一般性錯誤。”,不能快速地根據(jù)這個錯誤提示定位問題。比如說沒有釋放圖片資源時想再次訪問資源會報這個錯誤,想要保存圖片的文件夾不存在時也是提示這個錯誤??床怀鰜韰^(qū)別……
1. 保存到相同路徑的文件時要先釋放圖片資源,否則會報錯(GDI+中發(fā)生一般性錯誤)
Image img = Image.FromFile(imgPath); Bitmap bmp = new Bitmap(img); Graphics graphics = Graphics.FromImage(bmp); ... // 對圖片進行一些處理 img.Dispose(); // 釋放原圖資源 bmp.Save(imgPath); // 保存到原圖 graphics.Dispose(); // 圖片處理過程完成,剩余資源全部釋放 bmp.Dispose();
2. 使用完的資源記得要釋放。可以用 try..catch..finally 或者 using 的方式,這樣即使遇到代碼運行報錯也能及時釋放資源,更加保險。
try..catch...finally:把釋放資源的代碼寫到 finally 代碼段里。
Image img = Image.FromFile(imgPath); Bitmap bmp = new Bitmap(img); Graphics graphics = Graphics.FromImage(bmp); try { ... } catch (System.Exception ex) { throw ex; } finally { graphics.Dispose(); bmp.Dispose(); img.Dispose(); }
using:使用 using 語句創(chuàng)建的資源會在離開 using 代碼段時自動釋放該資源。
////// 縮放圖像 /// /// 原圖路徑 /// 目標圖寬度 /// 目標圖高度 ///public Bitmap GetThumbnail(string originalImagePath, int destWidth, int destHeight) { using (Image imgSource = Image.FromFile(originalImagePath)) { return GetThumbnail(imgSource, destWidth, destHeight); } }
3. 要保存圖片的文件夾一定要是已經(jīng)存在的,否則會報錯(GDI+中發(fā)生一般性錯誤)
eg:假設圖片要保存到 D:\test\output.png
string directory = @"D:\test\"; string fileName = "output.png"; // 檢查文件夾是否存在,不存在則先創(chuàng)建 if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } bmp.Save(directory + fileName);
以上是“C#利用GDI+畫圖的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注創(chuàng)新互聯(lián)成都網(wǎng)站設計公司行業(yè)資訊頻道!
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。