一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C# - C#利用GDI+畫圖的基礎實例教程

C#利用GDI+畫圖的基礎實例教程

2022-02-22 14:19Dandelion_drq C#

編寫圖形程序時需要使用GDI(Graphics Device Interface,圖形設備接口),所以通過網上的相關資料整理了這篇文章,下面這篇文章主要給大家介紹了關于C#利用GDI+畫圖基礎的相關資料,需要的朋友可以參考下。

前言

最近做一個微信公眾號服務,有一些簡單的圖片處理功能。主要就是用戶在頁面操作,前端做一些立刻顯示的效果,然后提交保存時后端真正修改原圖。

從程序設計的角度看,gdi包括兩部分:一部分是gdi對象,另一部分是gdi函數。gdi對象定義了gdi函數使用的工具和環境變量,而gdi函數使用gdi對象繪制各種圖形,在c#中,進行圖形程序編寫時用到的是gdi+(graphics device interface plus圖形設備接口)版本,gdi+是gdi的進一步擴展,它使我們編程更加方便。

c#中的gdi+就相當于java中的swing控件,是編寫圖形界面必不可缺的一個接口。gdi+繪圖最大的方便得益于c#的可視化編程,所有的控件只需要自己drag,然后place,最后cilck添加監聽方法。真的是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 對象。

比如:

?
1
2
3
4
private void form1_paint(object sender, painteventargs e)
{
 graphics g = e.graphics; // 創建畫板,這里的畫板是由form提供的.
}

不過本文討論的是其他場景,比如 asp.net mvc,或單純的控制臺程序。這些時候是沒有控件的,所以要用其他方法。

我一般用以下方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//
// 摘要:
//  從指定的 system.drawing.image 創建新的 system.drawing.graphics。
//
// 參數:
// image:
//  從中創建新 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);

其中的參數可以傳入 image 或 bitmap,因為 bitmap 是繼承自 image 的。

如何創建畫板

如果是要對原圖進行處理,比如旋轉圖片,添加文字等,可以直接通過原圖片獲得畫板對象。

?
1
2
image img = image.fromfile(imgpath);
graphics graphics = graphics.fromimage(img);

如果是要畫一個新的圖,可以通過要保存的圖片寬、高生成畫板。

?
1
2
bitmap bmp = new bitmap(width, height);
graphics graph = graphics.fromimage(bmp);

ps: graphics 本身是沒有提供構造函數來直接生成的。所以我們可以先創建一個需要保存圖片大小的 bitmap 位圖對象,然后再獲得畫板對象。

如何保存畫好的圖片

通過調用 img.save(savepath) 或者 bmp.save(savepath) 即可保存對象。

ps: bitmap 的 save 方法是直接繼承自 image 的。

gdi+ 的坐標系

gdi+ 的坐標系是個二維坐標系,不過又有點不一樣,它的原點是在左上角的。如下圖:

C#利用GDI+畫圖的基礎實例教程

使用 gdi+ 的一些注意事項

這里我忍不住要先吐槽一下,gdi+ 的報錯信息不太友好啊。經常只是返回一個“gdi+ 中發生一般性錯誤。”,不能快速地根據這個錯誤提示定位問題。比如說沒有釋放圖片資源時想再次訪問資源會報這個錯誤,想要保存圖片的文件夾不存在時也是提示這個錯誤。看不出來區別……

1. 保存到相同路徑的文件時要先釋放圖片資源,否則會報錯(gdi+中發生一般性錯誤)

?
1
2
3
4
5
6
7
8
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 代碼段里。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 語句創建的資源會在離開 using 代碼段時自動釋放該資源。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/// <summary>
/// 縮放圖像
/// </summary>
/// <param name="originalimagepath">原圖路徑</param>
/// <param name="destwidth">目標圖寬度</param>
/// <param name="destheight">目標圖高度</param>
/// <returns></returns>
public bitmap getthumbnail(string originalimagepath, int destwidth, int destheight)
{
 using (image imgsource = image.fromfile(originalimagepath))
 {
  return getthumbnail(imgsource, destwidth, destheight);
 }
}

3. 要保存圖片的文件夾一定要是已經存在的,否則會報錯(gdi+中發生一般性錯誤)

eg:假設圖片要保存到 d:\test\output.png

?
1
2
3
4
5
6
7
8
string directory = @"d:\test\";
string filename = "output.png";
// 檢查文件夾是否存在,不存在則先創建
if (!directory.exists(directory))
{
 directory.createdirectory(directory);
}
bmp.save(directory + filename);

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:http://www.cnblogs.com/dandelion-drq/p/use-gdiplus-to-draw-image-in-csharp.html

延伸 · 閱讀

精彩推薦
  • C#WPF 自定義雷達圖開發實例教程

    WPF 自定義雷達圖開發實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下...

    WinterFish13112021-12-06
  • C#C#裁剪,縮放,清晰度,水印處理操作示例

    C#裁剪,縮放,清晰度,水印處理操作示例

    這篇文章主要為大家詳細介紹了C#裁剪,縮放,清晰度,水印處理操作示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    吳 劍8332021-12-08
  • C#C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    這篇文章主要介紹了C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題,簡單描述了訪問者模式的定義并結合具體實例形式分析了C#使用訪問者模式解決長...

    GhostRider9502022-01-21
  • C#Unity3D實現虛擬按鈕控制人物移動效果

    Unity3D實現虛擬按鈕控制人物移動效果

    這篇文章主要為大家詳細介紹了Unity3D實現虛擬按鈕控制人物移動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    shenqingyu060520232410972022-03-11
  • C#C#通過KD樹進行距離最近點的查找

    C#通過KD樹進行距離最近點的查找

    這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    帆帆帆6112022-01-22
  • C#C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    這篇文章主要介紹了C# 實現對PPT文檔加密、解密及重置密碼的操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下...

    E-iceblue5012022-02-12
  • C#C#實現XML文件讀取

    C#實現XML文件讀取

    這篇文章主要為大家詳細介紹了C#實現XML文件讀取的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Just_for_Myself6702022-02-22
  • C#深入解析C#中的交錯數組與隱式類型的數組

    深入解析C#中的交錯數組與隱式類型的數組

    這篇文章主要介紹了深入解析C#中的交錯數組與隱式類型的數組,隱式類型的數組通常與匿名類型以及對象初始值設定項和集合初始值設定項一起使用,需要的...

    C#教程網6172021-11-09
主站蜘蛛池模板: 欧美sex另类孕妇 | 欧美日韩综合网在线观看 | 日韩亚洲欧美综合一区二区三区 | 日韩欧美一区二区不卡 | jiuse视频 | 国产精品第3页 | 免费看伦理片 | 日韩视频在线精品视频免费观看 | 国产精品久久国产精品99 | 久久日本片精品AAAAA国产 | 91久久色| 亚洲精品国产AV成人毛片 | 日韩精品视频观看 | 青青草国产精品 | 日韩一卡2卡3卡新区网站 | 五月色婷婷久久综合 | 狠狠久久久久综合网 | 久久综合老色鬼网站 | chinese男男gay| 欧美在线播放成人免费 | 被强上后我成瘾了小说 | 国产精品人人视频 | 亚洲国产成人精品不卡青青草原 | 午夜在线观看免费完整直播网页 | 国产思妍小仙女一二区 | 狠狠色综合久久婷婷色天使 | 免费我看视频在线观看 | 亚洲h片 | 亚州第一页 | 男人狂躁女人下面的视频免费 | 天天操丝袜 | 香蕉草莓视频 | 国产麻豆精品原创 | 97国产精品久久碰碰牛牛 | 日韩精品免费一区二区三区 | 黑人日白人 | 精品一区二区三区免费毛片 | 美女的隐私视频免费看软件 | 精品一久久香蕉国产线看播放 | 2020国产精品亚洲综合网 | 星空无限传媒xk8027穆娜 |