Silverlight C# 游戏开发:资源的处理,图像算法(二)
????? 也許說(shuō),圖像算法很過(guò)時(shí),那是許久以前的做法,可是作為Silverlight來(lái)說(shuō),我認(rèn)為非常有用,這些有趣的處理就像是在Web上實(shí)現(xiàn)了一個(gè)Photoshop,大大擴(kuò)展了發(fā)揮空間,很多算法不止PS在用,大多的圖片軟件也都在這樣的算法,你甚至可以把它們變成你的Silverlight版本的圖片處理軟件,然而,我們只談?dòng)螒蛑械膽?yīng)用,這些經(jīng)典的算法可以各種特效的處理,甚至將一個(gè)游戲的資源成N個(gè)資源,下面只是一張圖片,演示程序和源代碼在最后面:)
?
?
第一個(gè):色相清除
?
????? 色相清除,很簡(jiǎn)單,就是顏色值留下,將特定的顏色清除掉就能達(dá)到效果,上面這個(gè)效果RGB顏色分別只留下了一種,源代碼如下,這個(gè)處理類似在Photoshop中顏色通道的顯示,該應(yīng)用較為廣泛,如果你將下面的代碼稍作修改,就能完成一個(gè)同一張圖片的不同變化,比如說(shuō)綠色小怪、紅色小怪、藍(lán)色小怪、甚至紫色小怪,哈哈。
?
????????????WriteableBitmap?wb?=?new?WriteableBitmap(Image0.Source?as?BitmapSource);????????????WriteableBitmap?wb1?=?new?WriteableBitmap(Image0.Source?as?BitmapSource);
????????????WriteableBitmap?wb2?=?new?WriteableBitmap(Image0.Source?as?BitmapSource);
????????????//A?R?G?B?=>?[B,?G,?R,?A]
????????????for?(int?y?=?0;?y?<?wb.PixelHeight;?y++)
????????????{
????????????????for?(int?x?=?0;?x?<?wb.PixelWidth;?x++)
????????????????{
????????????????????int?pixel?=?wb.Pixels[y?*?wb.PixelWidth?+?x];
????????????????????byte[]?dd?=?BitConverter.GetBytes(pixel);
????????????????????dd[0]?=?0;
????????????????????dd[1]?=?0;
????????????????????wb.Pixels[y?*?wb.PixelWidth?+?x]?=?BitConverter.ToInt32(dd,?0);
????????????????????pixel?=?wb1.Pixels[y?*?wb1.PixelWidth?+?x];
????????????????????dd?=?BitConverter.GetBytes(pixel);
????????????????????dd[1]?=?0;
????????????????????dd[2]?=?0;
????????????????????wb1.Pixels[y?*?wb1.PixelWidth?+?x]?=?BitConverter.ToInt32(dd,?0);
????????????????????pixel?=?wb2.Pixels[y?*?wb2.PixelWidth?+?x];
????????????????????dd?=?BitConverter.GetBytes(pixel);
????????????????????dd[2]?=?0;
????????????????????dd[0]?=?0;
????????????????????wb2.Pixels[y?*?wb2.PixelWidth?+?x]?=?BitConverter.ToInt32(dd,?0);
????????????????}
????????????}
????????????Image1.Source?=?wb;
????????????Image2.Source?=?wb1;
????????????Image3.Source?=?wb2;
?
第二個(gè):Gamma值
?
?伽馬值,我們一般稱之為顏色曲線,在以前電視機(jī)的顯像就是這個(gè)來(lái)操縱的,當(dāng)然了,gamma 校正是指更改 gamma 值以匹配監(jiān)視器的中間灰度,校正補(bǔ)償了不同輸出設(shè)備存在的顏色顯示差異,從而使圖像在不同的監(jiān)視器上呈現(xiàn)出相同的效果,這個(gè)方法在顏色區(qū)分中可以做多種不同的效果,例如夢(mèng)境、恐懼等,部分源代碼如下。?
????????private?byte[]?MakeGammaArray(double?color)????????{
????????????byte[]?gammaArray?=?new?byte[256];
????????????for?(int?i?=?0;?i?<?256;?++i)
????????????{
????????????????gammaArray[i]?=?
??????????????????????(byte)Math.Min(255,?(int)((255.0?*?Math.Pow(i?/?255.0,?1.0?/?color))?+?0.5));
????????????}
????????????return?gammaArray;
????????}
?
?第三個(gè):亮度
?
?
?
亮度的原理很簡(jiǎn)單,只是將顏色數(shù)值增加一個(gè)偏移,雖然以正負(fù)255來(lái)計(jì)算,無(wú)非就是-1.0和+1.0的問(wèn)題,顏色加值最后得到一張圖片的亮度減暗或者加深,這個(gè)用法在很多游戲中很有用,你可以做一些微調(diào),設(shè)置一些特別的效果,例如被電擊之后的感覺(jué),或者遭到暗屬性的Debuff,算法就在下面,并不難,只需要傳入?yún)?shù)brightness就行了。
?
????????private?void?SetBrightness(int?brightness)????????{
????????????if?(brightness?<?-255)?brightness?=?-255;
????????????if?(brightness?>?255)?brightness?=?255;
????????????WriteableBitmap?wb?=?new?WriteableBitmap(Image0.Source?as?BitmapSource);
????????????for?(int?y?=?0;?y?<?wb.PixelHeight;?y++)
????????????{
????????????????for?(int?x?=?0;?x?<?wb.PixelWidth;?x++)
????????????????{
????????????????????int?pixel?=?wb.Pixels[y?*?wb.PixelWidth?+?x];
????????????????????byte[]?dd?=?BitConverter.GetBytes(pixel);
????????????????????int?B?=?(int)dd[0]?+?brightness;
????????????????????int?G?=?(int)dd[1]?+?brightness;
????????????????????int?R?=?(int)dd[2]?+?brightness;
????????????????????if?(B?<?0)?B?=?0;
????????????????????if?(B?>?255)?B?=?255;
????????????????????if?(G?<?0)?G?=?0;
????????????????????if?(G?>?255)?G?=?255;
????????????????????if?(R?<?0)?R?=?0;
????????????????????if?(R?>?255)?R?=?255;
????????????????????dd[0]?=?(byte)B;
????????????????????dd[1]?=?(byte)G;
????????????????????dd[2]?=?(byte)R;
????????????????????wb.Pixels[y?*?wb.PixelWidth?+?x]?=?BitConverter.ToInt32(dd,?0);
????????????????}
????????????}
????????????Image1.Source?=?wb;
????????}
?
?
第四個(gè):對(duì)比度
?
與亮度一樣,是一個(gè)常用的算法,將顏色的亮度和飽和度同時(shí)增加,以達(dá)到黑的更黑,白的更白,這種方法在處理特效時(shí)相當(dāng)有用,?依據(jù)不同的情況使用不同的效果,算法給出如下,它是一個(gè)設(shè)置型的處理方案,與亮度一樣,傳入一個(gè)參數(shù)即可。
????????private?void?SetContrast(double?contrast)????????{
????????????if?(contrast?<?-100)?contrast?=?-100;
????????????if?(contrast?>?100)?contrast?=?100;
????????????contrast?=?(100.0?+?contrast)?/?100.0;
????????????contrast?*=?contrast;
????????????WriteableBitmap?wb?=?new?WriteableBitmap(Image0.Source?as?BitmapSource);
????????????for?(int?y?=?0;?y?<?wb.PixelHeight;?y++)
????????????{
????????????????for?(int?x?=?0;?x?<?wb.PixelWidth;?x++)
????????????????{
????????????????????int?pixel?=?wb.Pixels[y?*?wb.PixelWidth?+?x];
????????????????????byte[]?dd?=?BitConverter.GetBytes(pixel);
????????????????????double?pR?=?(double)dd[2]?/?255.0;
????????????????????pR?-=?0.5;
????????????????????pR?*=?contrast;
????????????????????pR?+=?0.5;
????????????????????pR?*=?255;
????????????????????if?(pR?<?0)?pR?=?0;
????????????????????if?(pR?>?255)?pR?=?255;
????????????????????double?pG?=?(double)dd[1]?/?255.0;
????????????????????pG?-=?0.5;
????????????????????pG?*=?contrast;
????????????????????pG?+=?0.5;
????????????????????pG?*=?255;
????????????????????if?(pG?<?0)?pG?=?0;
????????????????????if?(pG?>?255)?pG?=?255;
????????????????????double?pB?=?(double)dd[0]?/?255.0;
????????????????????pB?-=?0.5;
????????????????????pB?*=?contrast;
????????????????????pB?+=?0.5;
????????????????????pB?*=?255;
????????????????????if?(pB?<?0)?pB?=?0;
????????????????????if?(pB?>?255)?pB?=?255;
????????????????????dd[2]?=?(byte)pR;
????????????????????dd[1]?=?(byte)pG;
????????????????????dd[0]?=?(byte)pB;
????????????????????wb.Pixels[y?*?wb.PixelWidth?+?x]?=?BitConverter.ToInt32(dd,?0);
????????????????}
????????????}
????????????Image1.Source?=?wb;
????????}
第五個(gè):灰度
?
我以前一直認(rèn)為是取RGB的平均值,后來(lái)實(shí)驗(yàn)之后才知道,這樣得到的效果很不好,原來(lái)顏色也占有不同的比重,知道比重值之后,我們就能將一張顏色漂亮的圖片變成灰度圖了,這個(gè)用法非常普遍,比如說(shuō)死亡的效果,不需要再準(zhǔn)備一套同樣的灰度圖片,下面是源代碼,均值分別為0.299,0.587,0.114。
????????????WriteableBitmap?wb?=?new?WriteableBitmap(Image0.Source?as?BitmapSource);????????????for?(int?y?=?0;?y?<?wb.PixelHeight;?y++)
????????????{
????????????????for?(int?x?=?0;?x?<?wb.PixelWidth;?x++)
????????????????{
????????????????????int?pixel?=?wb.Pixels[y?*?wb.PixelWidth?+?x];
????????????????????byte[]?dd?=?BitConverter.GetBytes(pixel);
????????????????????double?R?=?dd[2];
????????????????????double?G?=?dd[1];
????????????????????double?B?=?dd[0];
????????????????????byte?gray?=?(byte)(0.299?*?R?+?0.587?*?G?+?0.114?*?B);
????????????????????dd[0]?=?dd[1]?=?dd[2]?=?gray;
????????????????????wb.Pixels[y?*?wb.PixelWidth?+?x]?=?BitConverter.ToInt32(dd,?0);
????????????????}
????????????}
????????????Image1.Source?=?wb;
?
第六個(gè):反色
?
反色的效果應(yīng)用不甚廣泛,它很簡(jiǎn)單,有的時(shí)候用在讓人覺(jué)得詭異的地方比較好,我記得動(dòng)漫中常有這樣的尷尬環(huán)境表示方法,或者過(guò)場(chǎng),反正算法并不難,參看下述源代碼,公式為FF=FF-0:
????????????WriteableBitmap?wb?=?new?WriteableBitmap(Image0.Source?as?BitmapSource);????????????for?(int?y?=?0;?y?<?wb.PixelHeight;?y++)
????????????{
????????????????for?(int?x?=?0;?x?<?wb.PixelWidth;?x++)
????????????????{
????????????????????int?pixel?=?wb.Pixels[y?*?wb.PixelWidth?+?x];
????????????????????byte[]?dd?=?BitConverter.GetBytes(pixel);
????????????????????
????????????????????dd[2]?=?(byte)(255?-?dd[2]);
????????????????????dd[1]?=?(byte)(255?-?dd[1]);
????????????????????dd[0]?=?(byte)(255?-?dd[0]);
????????????????????wb.Pixels[y?*?wb.PixelWidth?+?x]?=?BitConverter.ToInt32(dd,?0);
????????????????}
????????????}
????????????Image1.Source?=?wb;
?綜述:
我們今天一起搞了六種常見(jiàn)的圖像算法,其實(shí)都是在操作像素點(diǎn),將像素做了一些修改,但是c#里運(yùn)算速度不是很理想,主要是我的水平還是很低級(jí),只好用暴力的方法解決,以前在C++中,我們可以使用匯編對(duì)內(nèi)存進(jìn)行操作,處理速度非常的快,我們?cè)赟ilverlight中做到同等的處理可能要做一些優(yōu)化工作,比如預(yù)先載入,提前處理,或者弄個(gè)另外線程搞定,不過(guò)不論怎么說(shuō),性能和效率都是我們最關(guān)注的點(diǎn),游戲是非常要求速度的交互程序,所以,我們需要考慮的更多,到底是用性能換空間,還是用空間換性能,都是游戲開(kāi)發(fā)者們一直在挑戰(zhàn)的題目。
下面是本篇節(jié)的Silverlight程序:)需要源代碼的在這里下載:源代碼在這里
?
posted on 2010-03-23 09:43 nowpaper 閱讀(...) 評(píng)論(...) 編輯 收藏
轉(zhuǎn)載于:https://www.cnblogs.com/nowpaper/archive/2010/03/23/1692057.html
總結(jié)
以上是生活随笔為你收集整理的Silverlight C# 游戏开发:资源的处理,图像算法(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Jeecg 初级入门
- 下一篇: .NET(C#) Internals: