Silverlight C# 游戏开发:资源的处理,图像算法(二)
????? 也許說,圖像算法很過時,那是許久以前的做法,可是作為Silverlight來說,我認為非常有用,這些有趣的處理就像是在Web上實現了一個Photoshop,大大擴展了發揮空間,很多算法不止PS在用,大多的圖片軟件也都在這樣的算法,你甚至可以把它們變成你的Silverlight版本的圖片處理軟件,然而,我們只談游戲中的應用,這些經典的算法可以各種特效的處理,甚至將一個游戲的資源成N個資源,下面只是一張圖片,演示程序和源代碼在最后面:)
?
?
第一個:色相清除
?
????? 色相清除,很簡單,就是顏色值留下,將特定的顏色清除掉就能達到效果,上面這個效果RGB顏色分別只留下了一種,源代碼如下,這個處理類似在Photoshop中顏色通道的顯示,該應用較為廣泛,如果你將下面的代碼稍作修改,就能完成一個同一張圖片的不同變化,比如說綠色小怪、紅色小怪、藍色小怪、甚至紫色小怪,哈哈。
?
????????????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;
?
第二個:Gamma值
?
?伽馬值,我們一般稱之為顏色曲線,在以前電視機的顯像就是這個來操縱的,當然了,gamma 校正是指更改 gamma 值以匹配監視器的中間灰度,校正補償了不同輸出設備存在的顏色顯示差異,從而使圖像在不同的監視器上呈現出相同的效果,這個方法在顏色區分中可以做多種不同的效果,例如夢境、恐懼等,部分源代碼如下。?
????????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;
????????}
?
?第三個:亮度
?
?
?
亮度的原理很簡單,只是將顏色數值增加一個偏移,雖然以正負255來計算,無非就是-1.0和+1.0的問題,顏色加值最后得到一張圖片的亮度減暗或者加深,這個用法在很多游戲中很有用,你可以做一些微調,設置一些特別的效果,例如被電擊之后的感覺,或者遭到暗屬性的Debuff,算法就在下面,并不難,只需要傳入參數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;
????????}
?
?
第四個:對比度
?
與亮度一樣,是一個常用的算法,將顏色的亮度和飽和度同時增加,以達到黑的更黑,白的更白,這種方法在處理特效時相當有用,?依據不同的情況使用不同的效果,算法給出如下,它是一個設置型的處理方案,與亮度一樣,傳入一個參數即可。
????????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;
????????}
第五個:灰度
?
我以前一直認為是取RGB的平均值,后來實驗之后才知道,這樣得到的效果很不好,原來顏色也占有不同的比重,知道比重值之后,我們就能將一張顏色漂亮的圖片變成灰度圖了,這個用法非常普遍,比如說死亡的效果,不需要再準備一套同樣的灰度圖片,下面是源代碼,均值分別為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;
?
第六個:反色
?
反色的效果應用不甚廣泛,它很簡單,有的時候用在讓人覺得詭異的地方比較好,我記得動漫中常有這樣的尷尬環境表示方法,或者過場,反正算法并不難,參看下述源代碼,公式為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;
?綜述:
我們今天一起搞了六種常見的圖像算法,其實都是在操作像素點,將像素做了一些修改,但是c#里運算速度不是很理想,主要是我的水平還是很低級,只好用暴力的方法解決,以前在C++中,我們可以使用匯編對內存進行操作,處理速度非常的快,我們在Silverlight中做到同等的處理可能要做一些優化工作,比如預先載入,提前處理,或者弄個另外線程搞定,不過不論怎么說,性能和效率都是我們最關注的點,游戲是非常要求速度的交互程序,所以,我們需要考慮的更多,到底是用性能換空間,還是用空間換性能,都是游戲開發者們一直在挑戰的題目。
下面是本篇節的Silverlight程序:)需要源代碼的在這里下載:源代碼在這里
?
posted on 2010-03-23 09:43 nowpaper 閱讀(...) 評論(...) 編輯 收藏
轉載于:https://www.cnblogs.com/nowpaper/archive/2010/03/23/1692057.html
總結
以上是生活随笔為你收集整理的Silverlight C# 游戏开发:资源的处理,图像算法(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Jeecg 初级入门
- 下一篇: 职场 | 3天准备5天面试,跳槽完成