很久之前,就想寫一系列C#圖像程式設計的文章,但始終沒有下筆,其主要原因有二:(1)我的C#圖像處理庫 Geb.Image 庫在大幅度變動中;(2)沒有找到一個很好的示範工具。現在,對于第一個問題,Geb.Image庫的基本結構已經确定了;對于第二個問題,選擇了LinqPad作為C#圖像程式設計和示範工具,輕巧簡便。就從現在開始吧。
假設您熟悉C#程式設計,且電腦中有 32 位的.Net 4.0 環境。在此基礎上,我們開始搭建C# 圖像程式設計的實驗環境。
第一步:下載下傳安裝 LinqPad。
第二步:下載下傳Geb.Image類庫
其目錄結構如上圖。這裡,我們隻使用其中的dll目錄和scripts目錄。顧名思義,dll 就是一些基本的 dll,scripts 就是本系列文章所寫的 C# 腳本。
第三步:設定 LinqPad
打開 LinqPad ,按 【F4】快捷鍵,進入 Query Properties 設定界面,在“Additional References”頁籤中,将dll目錄中的dll加入進去。
然後,在“Additional Namespace Imports”裡加入Geb.Image,Geb.Utils和Geb.Utils.WinForm 三個命名空間,點選“Set as Default for new queries” 儲存:
這樣,我們就添加了必要的 dll 引用,添加了常用的命名空間。
接着,點選LinqPad左下側的“Set Folder ... ”連結,将 scripts 目錄設定為工作目錄:
工作目錄中顯示的每一個檔案便是一個C#腳本檔案。輕按兩下可加載檔案。
在工作目錄中,輕按兩下“1-1-顯示圖檔”,可看到:
該腳本的作用是加載顯示圖像。在運作之前,需要将 baseDir 目錄更改為 scripts/img 目錄的實際路徑。點選綠色三角形按鈕,一副熟悉的面孔出現了:
下面,我們以空姐的照片為測試照片,來實作夜光特效算法:
夜光特效實作起來非常簡單:将圖像中的每個像素的Red值修改為目前值的1/2即可。程式檔案為scripts\001\1-2-夜光特效.linq,這裡通過四種方法來實作這一功能,來示範像素操作:
<code>String baseDir =</code><code>"E:\\MyWorkspace\\DotNetWorkspace\\01_Public_Geb.Image\\scripts\\img\\"</code><code>;</code>
<code>unsafe</code> <code>void</code> <code>Main()</code>
<code>{</code>
<code> </code><code>ImageRgb24 img =</code><code>new</code> <code>ImageRgb24(baseDir +</code><code>"cjk.jpg"</code><code>);</code>
<code> </code><code>img.ShowDialog(</code><code>"img"</code><code>);</code>
<code> </code>
<code> </code><code>// 将圖像看作連續的記憶體,通過偏移量來通路</code>
<code> </code><code>ImageRgb24 img2 = img.Clone();</code>
<code> </code><code>for</code><code>(</code><code>int</code> <code>i = 0; i < img2.Length; i++)</code>
<code> </code><code>{</code>
<code> </code><code>Rgb24 p= img2[i];</code>
<code> </code><code>p.Red = (Byte)(p.Red/2);</code>
<code> </code><code>img2[i] = p;</code>
<code> </code><code>}</code>
<code> </code><code>img2.ShowDialog(</code><code>"img2"</code><code>);</code>
<code> </code><code>// 将圖像看作一個二維“表格”,通過行和列坐标來通路</code>
<code> </code><code>ImageRgb24 img3 = img.Clone();</code>
<code> </code><code>for</code><code>(</code><code>int</code> <code>row = 0; row < img3.Height; row++)</code>
<code> </code><code>for</code><code>(</code><code>int</code> <code>col = 0; col < img3.Width; col ++)</code>
<code> </code><code>{</code>
<code> </code><code>Rgb24 p= img3[row,col];</code>
<code> </code><code>p.Red = (Byte)(p.Red/2);</code>
<code> </code><code>img3[row,col] = p;</code>
<code> </code><code>}</code>
<code> </code><code>img3.ShowDialog(</code><code>"img3"</code><code>);</code>
<code> </code><code>// 直接通過指針通路</code>
<code> </code><code>ImageRgb24 img4 = img.Clone();</code>
<code> </code><code>Rgb24* p = img4.Start;</code>
<code> </code><code>Rgb24* pEnd = p + img4.Length;</code>
<code> </code><code>while</code><code>(p != pEnd)</code>
<code> </code><code>p->Red = (Byte)(p->Red/2);</code>
<code> </code><code>p++;</code>
<code> </code><code>img4.ShowDialog(</code><code>"img4"</code><code>);</code>
<code> </code><code>// 通過lambda表達式通路</code>
<code> </code><code>ImageRgb24 img5 = img.Clone();</code>
<code> </code><code>img5.ForEach((Rgb24* p)=>{p->Red = (Byte)(p->Red/2);});</code>
<code> </code><code>img5.ShowDialog(</code><code>"img5"</code><code>);</code>
<code> </code><code>// Dispose 可以釋放圖像所占非管理記憶體。如果不Dispose,當GC銷毀對象時,也會釋放非管理記憶體。</code>
<code> </code><code>// img.Dispose();</code>
<code> </code><code>// img2.Dispose();</code>
<code> </code><code>// img3.Dispose();</code>
<code> </code><code>// img4.Dispose();</code>
<code> </code><code>// img5.Dispose();</code>
<code>}</code>
是不是很簡單呢?下面是娛樂時間。
為什麼用空姐作為示範圖檔呢?讓我們從刀妹說起吧。
在《英雄聯盟》遊戲中有個外号“刀鋒意志”的英雄——艾瑞莉娅,俗稱刀妹。刀妹是一個暴力妹紙——“那把劍狂亂飛舞,仿佛蘸血為畫”。
由于過于暴力,刀妹屢次被削弱,有說被連續削弱12次,有說22次。以至于“某某太強了我們來削弱一下刀妹吧!”成了網絡流行語了:蓋倫太強了,我們來削弱一下刀妹吧;卡牌太強了,我們來削弱一下刀妹吧;今天天氣不錯 我們來削弱一下刀妹吧 。。。
在圖像處理界,也有一個無所不在的妹紙,Lena:
Lena 是 1972年的一期花花公子封面女郎,自從1973年,某同學将這張照片用在論文中後,這張圖檔成了最常用的測試圖檔了,幾乎在每本圖像處理書中都可以看到她。
在地球上各個角落裡,這樣的聲音此起彼伏,曆經四十年而不衰:
程式寫完了,我們用Lena來測試下吧; 算法優化了,我們用Lena來測試下吧; ……
在東方,空姐比Lena更具有親和力,俺就不以Lena為測試圖檔了,代之以空姐。
程式寫完了,我們用空姐來測試下吧; 算法優化了,我們用空姐來測試下吧; 本文轉自xiaotie部落格園部落格,原文連結http://www.cnblogs.com/xiaotie/archive/2013/04/09/3009794.html如需轉載請自行聯系原作者 xiaotie 集異璧實驗室(GEBLAB)