国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C# > 正文

C#利用GDI+畫(huà)圖的基礎(chǔ)實(shí)例教程

2020-01-24 00:19:00
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

前言

最近做一個(gè)微信公眾號(hào)服務(wù),有一些簡(jiǎn)單的圖片處理功能。主要就是用戶在頁(yè)面操作,前端做一些立刻顯示的效果,然后提交保存時(shí)后端真正修改原圖。

從程序設(shè)計(jì)的角度看,GDI包括兩部分:一部分是GDI對(duì)象,另一部分是GDI函數(shù)。GDI對(duì)象定義了GDI函數(shù)使用的工具和環(huán)境變量,而GDI函數(shù)使用GDI對(duì)象繪制各種圖形,在C#中,進(jìn)行圖形程序編寫(xiě)時(shí)用到的是GDI+(Graphics Device Interface Plus圖形設(shè)備接口)版本,GDI+是GDI的進(jìn)一步擴(kuò)展,它使我們編程更加方便。

C#中的GDI+就相當(dāng)于java中的Swing控件,是編寫(xiě)圖形界面必不可缺的一個(gè)接口。GDI+繪圖最大的方便得益于C#的可視化編程,所有的控件只需要自己Drag,然后Place,最后Cilck添加監(jiān)聽(tīng)方法。真的是too young too simple。

我們的后端是 ASP.NET,也就是 C# 語(yǔ)言了,C# 本身處理圖片還是比較方便的,使用 GDI+ 就好,只需要添加 System.Drawing 引用,不需要任何第三方庫(kù)。于是最近也用到一些比較常用的 GDI+ 圖片處理方法,就整理一下做個(gè)記錄了。

這個(gè)題目大概會(huì)寫(xiě)幾篇文章,第一篇先簡(jiǎn)單介紹一下 GDI+ 的常用對(duì)象,以及一些使用時(shí)候的注意事項(xiàng),后面會(huì)挑一些項(xiàng)目中做過(guò)的比較有用的處理過(guò)程來(lái)介紹一下。

廢話不多說(shuō),開(kāi)始進(jìn)入正題。

需要用到的類

使用 GDI+ 畫(huà)圖會(huì)用到的幾個(gè)常用的類有:Graphics、Bitmap、Image。

其中 Graphics 是畫(huà)板。這個(gè)類包含了許多畫(huà)圖的方法,包括畫(huà)圖片(DrawImage),畫(huà)線(DrawLine),畫(huà)圓(DrawEllipse、FillEllipse),寫(xiě)字(DrawString)等等。簡(jiǎn)單說(shuō)使用這個(gè)類可以完成我們需要的大部分工作。

生成一個(gè) Graphics 對(duì)象需要用到 Image 或者 Bitmap。

PS: Winform 下可以直接從窗體或控件的事件中引用 Graphics 對(duì)象。

比如:

 private void Form1_Paint(object sender, PaintEventArgs e) {  Graphics g = e.Graphics; // 創(chuàng)建畫(huà)板,這里的畫(huà)板是由Form提供的. }

不過(guò)本文討論的是其他場(chǎng)景,比如 ASP.NET MVC,或單純的控制臺(tái)程序。這些時(shí)候是沒(méi)有控件的,所以要用其他方法。

我一般用以下方法:

//// 摘要://  從指定的 System.Drawing.Image 創(chuàng)建新的 System.Drawing.Graphics。//// 參數(shù):// image://  從中創(chuàng)建新 System.Drawing.Graphics 的 System.Drawing.Image。//// 返回結(jié)果://  此方法為指定的 System.Drawing.Image 返回一個(gè)新的 System.Drawing.Graphics。//// 異常:// T:System.ArgumentNullException://  image 為 null。//// T:System.Exception://  image 具有索引像素格式,或者格式未定義。public static Graphics FromImage(Image image);

其中的參數(shù)可以傳入 Image 或 Bitmap,因?yàn)?Bitmap 是繼承自 Image 的。

如何創(chuàng)建畫(huà)板

如果是要對(duì)原圖進(jìn)行處理,比如旋轉(zhuǎn)圖片,添加文字等,可以直接通過(guò)原圖片獲得畫(huà)板對(duì)象。

Image img = Image.FromFile(imgPath);Graphics graphics = Graphics.FromImage(img);

如果是要畫(huà)一個(gè)新的圖,可以通過(guò)要保存的圖片寬、高生成畫(huà)板。

Bitmap bmp = new Bitmap(width, height);Graphics graph = Graphics.FromImage(bmp);

PS: Graphics 本身是沒(méi)有提供構(gòu)造函數(shù)來(lái)直接生成的。所以我們可以先創(chuàng)建一個(gè)需要保存圖片大小的 Bitmap 位圖對(duì)象,然后再獲得畫(huà)板對(duì)象。

如何保存畫(huà)好的圖片

通過(guò)調(diào)用 img.Save(savePath) 或者 bmp.Save(savePath) 即可保存對(duì)象。

PS: Bitmap 的 Save 方法是直接繼承自 Image 的。

GDI+ 的坐標(biāo)系

GDI+ 的坐標(biāo)系是個(gè)二維坐標(biāo)系,不過(guò)又有點(diǎn)不一樣,它的原點(diǎn)是在左上角的。如下圖:


使用 GDI+ 的一些注意事項(xiàng)

這里我忍不住要先吐槽一下,GDI+ 的報(bào)錯(cuò)信息不太友好啊。經(jīng)常只是返回一個(gè)“GDI+ 中發(fā)生一般性錯(cuò)誤。”,不能快速地根據(jù)這個(gè)錯(cuò)誤提示定位問(wèn)題。比如說(shuō)沒(méi)有釋放圖片資源時(shí)想再次訪問(wèn)資源會(huì)報(bào)這個(gè)錯(cuò)誤,想要保存圖片的文件夾不存在時(shí)也是提示這個(gè)錯(cuò)誤。看不出來(lái)區(qū)別……

1. 保存到相同路徑的文件時(shí)要先釋放圖片資源,否則會(huì)報(bào)錯(cuò)(GDI+中發(fā)生一般性錯(cuò)誤)

Image img = Image.FromFile(imgPath);Bitmap bmp = new Bitmap(img);Graphics graphics = Graphics.FromImage(bmp);... // 對(duì)圖片進(jìn)行一些處理img.Dispose(); // 釋放原圖資源bmp.Save(imgPath); // 保存到原圖graphics.Dispose(); // 圖片處理過(guò)程完成,剩余資源全部釋放bmp.Dispose();

2. 使用完的資源記得要釋放。可以用 try..catch..finally 或者 using 的方式,這樣即使遇到代碼運(yùn)行報(bào)錯(cuò)也能及時(shí)釋放資源,更加保險(xiǎn)。

try..catch...finally:把釋放資源的代碼寫(xiě)到 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 語(yǔ)句創(chuàng)建的資源會(huì)在離開(kāi) using 代碼段時(shí)自動(dòng)釋放該資源。

/// <summary>/// 縮放圖像/// </summary>/// <param name="originalImagePath">原圖路徑</param>/// <param name="destWidth">目標(biāo)圖寬度</param>/// <param name="destHeight">目標(biāo)圖高度</param>/// <returns></returns>public Bitmap GetThumbnail(string originalImagePath, int destWidth, int destHeight){ using (Image imgSource = Image.FromFile(originalImagePath)) {  return GetThumbnail(imgSource, destWidth, destHeight); }}

3. 要保存圖片的文件夾一定要是已經(jīng)存在的,否則會(huì)報(bào)錯(cuò)(GDI+中發(fā)生一般性錯(cuò)誤)

eg:假設(shè)圖片要保存到 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);

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)武林網(wǎng)的支持。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 金湖县| 二手房| 尤溪县| 通渭县| 门头沟区| 汝城县| 宿迁市| 惠东县| 漾濞| 库车县| 门源| 民乐县| 麻栗坡县| 荥阳市| 年辖:市辖区| 南木林县| 汕头市| 娱乐| 城口县| 辽宁省| 五常市| 沾益县| 板桥市| 灯塔市| 澄迈县| 八宿县| 托里县| 承德市| 阜康市| 榕江县| 衢州市| 包头市| 南投县| 许昌市| 启东市| 上蔡县| 商洛市| 肃北| 沙湾县| 色达县| 洛川县|