Silverlight游戏开发中的资源的处理和图像算法2

      本文紧接上一篇,上篇中,我们主要讲述了silverlight游戏开发中的资源调用和配置问题,而本文则主要讲述图像算法,包括各种图像特效的处理以及何时利用何种算法最为有效等.也许说,图像算法很过时,那是许久以前的做法,可是作为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;
            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;

wakuaiyu -
共有0个回答