正文

C#图像处理――前奏(二)2009-06-02 21:36:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/emath/44108.html

分享到:

   指针法

C/C++的习惯,不是C#的特点

public static Bitmap  RGB2Gray(Bitmap srcBitmap)

        {

            int wide = srcBitmap.Width;

            int height = srcBitmap.Height ;

            Rectangle rect = new Rectangle(0, 0, wide, height);

            BitmapData srcBmData = srcBitmap.LockBits(rect,

                      ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            Bitmap dstBitmap = CreateGrayscaleImage(wide, height);

            BitmapData dstBmData = dstBitmap.LockBits(rect,

                      ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

   

            System.IntPtr srcScan = srcBmData.Scan0;

            System.IntPtr dstScan = dstBmData.Scan0;

            Unsafe  //启动不安全代码

            {

                byte* srcP = (byte*)(void*) srcScan;

                byte* dstP = (byte*)(void*) dstScan;

                int srcOffset = srcBmData.Stride - wide  * 3;

                int dstOffset = dstBmData.Stride  - wide ;

                byte red, green, blue;

                for (int y = 0; y < height; y++)

                {

                    for (int x = 0; x <wide ; x++, srcP += 3, dstP++)

                    {

                        blue = srcP [0];

                        green = srcP [1];

                        red = srcP [2];

                        * dstP = (byte)(.299 * red + .587 * green + .114 * blue);

                       

                    }

                    srcP += srcOffset;

                    dstP += dstOffset;

                }

            }

            srcBitmap.UnlockBits(srcBmData);

            dstBitmap.UnlockBits(dstBmData );

            return dstBitmap;

 

        }//#

五.   矩阵法

并不是什么新方法,只是将图像数据分做R,G,B三个矩阵(二维数组)存储,类似MATLAB的习惯.

       public static bool GetRGB(Bitmap Source, out int[,] R, out int[,] G, out int[,] B)

        {

            try

            {

                int iWidth = Source.Width;

                int iHeight = Source.Height;

 

                Rectangle rect = new Rectangle(0, 0, iWidth, iHeight);

                System.Drawing.Imaging.BitmapData bmpData = Source.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, Source.PixelFormat);

                IntPtr iPtr = bmpData.Scan0;

 

                int iBytes = iWidth * iHeight * 3;

                byte[] PixelValues = new byte[iBytes];

                System.Runtime.InteropServices.Marshal.Copy(iPtr, PixelValues, 0, iBytes);

                Source.UnlockBits(bmpData);

 

                // 注意这个地方图像的两维方向与数组两维的方向是转置的关系

 

                R = new int[iHeight, iWidth];

                G = new int[iHeight, iWidth];

                B = new int[iHeight, iWidth];

 

                int iPoint = 0;

 

                for (int i = 0; i < iHeight; i++)

                {

                    for (int j = 0; j < iWidth; j++)

                    {

                        // 注意,Windows 中三基色的排列顺序是 BGR 而不是 RGB

                        B[i, j] = Convert.ToInt32(PixelValues[iPoint++]);

                        G[i, j] = Convert.ToInt32(PixelValues[iPoint++]);

                        R[i, j] = Convert.ToInt32(PixelValues[iPoint++]);

                    }

                }

 

                return true;

            }

            catch (Exception)

            {

                R = null;

                G = null;

                B = null;

 

                return false;

            }

        }//#

        public static Bitmap FromRGB(int[,] R, int[,] G, int[,] B)

        {

            int iWidth = G.GetLength(1);

            int iHeight = G.GetLength(0);

            Bitmap Result = new Bitmap(iWidth, iHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

 

            Rectangle rect = new Rectangle(0, 0, iWidth, iHeight);

            System.Drawing.Imaging.BitmapData bmpData = Result.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            IntPtr iPtr = bmpData.Scan0;

            int iStride = bmpData.Stride;

 

            int iBytes = iWidth * iHeight * 3;

            byte[] PixelValues = new byte[iBytes];

 

            int iPoint = 0;

 

            for (int i = 0; i < iHeight; i++)

                for (int j = 0; j < iWidth; j++)

                {

                    int iG = G[i, j];

                    int iB = B[i, j];

                    int iR = R[i, j];

                    PixelValues[iPoint] = Convert.ToByte(iB);

                    PixelValues[iPoint + 1] = Convert.ToByte(iG);

                    PixelValues[iPoint + 2] = Convert.ToByte(iR);

                    iPoint += 3;

                }

 

            System.Runtime.InteropServices.Marshal.Copy(PixelValues, 0, iPtr, iBytes);

 

            Result.UnlockBits(bmpData);

 

            return Result;

        }//#

        public static bool  GetGray(Bitmap srcBitmap, out byte [,] gray)

        {

 

            Bitmap tempBitmap;

            if (srcBitmap.PixelFormat != PixelFormat.Format8bppIndexed)

                tempBitmap = ImageProcess.Image.Gray(srcBitmap);

            else

                tempBitmap = srcBitmap;

            int wide = tempBitmap.Width;

            int height = tempBitmap.Height;

            gray = new byte [height, wide];

            BitmapData gbmData = tempBitmap.LockBits(new Rectangle(0, 0, wide, height),

                  ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

            System.IntPtr ScanG = gbmData.Scan0;

            int gOffset = gbmData.Stride - wide;

            unsafe

            {

                byte* g = (byte*)(void*)ScanG;

                // for each pixel

                for (int y = 0; y < height; y++)

                {

                    // for each pixel

                    for (int x = 0; x < wide; x++, g++)

                    {

                        gray[y ,x ] =*g;

                    }

                    g += gOffset;

                }

            }

 

            tempBitmap.UnlockBits(gbmData);

 

            return true ;

 

        }//#

        public static Bitmap FromGray(byte [,] Gray)

        {

            int iWidth = Gray.GetLength(1);

            int iHeight = Gray.GetLength(0);

            Bitmap dstBitmap = ImageProcess.Image.CreateGrayscaleImage(iWidth, iHeight);

            BitmapData gbmData = dstBitmap.LockBits(new Rectangle(0, 0, iWidth, iHeight),

                      ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

            System.IntPtr ScanG = gbmData.Scan0;

            int gOffset = gbmData.Stride - iWidth;

            unsafe

            {

                byte* g = (byte*)(void*)ScanG;

 

                // 注意这个地方图像的两维方向与数组两维的方向是转置的关系

 

                for (int i = 0; i < iHeight; i++)

                {

                    for (int j = 0; j < iWidth; j++)

                    {

 

                        *g=(byte )Gray[i, j] ;

                        g++;

                    }

                    g += gOffset;

                }

            }

 

            dstBitmap.UnlockBits(gbmData);

 

            return dstBitmap;

        } //#

/*********************************补充******************************************/

         /// <summary>

         /// Create and initialize grayscale image

         /// </summary>

         public static Bitmap CreateGrayscaleImage( int width, int height )

         {

              // create new image

              Bitmap bmp = new Bitmap( width, height, PixelFormat.Format8bppIndexed );

              // set palette to grayscale

              SetGrayscalePalette( bmp );

              // return new image

              return bmp;

         }//#

 

         /// <summary>

         /// Set pallete of the image to grayscale

         /// </summary>

         public static void SetGrayscalePalette( Bitmap srcImg )

         {

              // check pixel format

              if ( srcImg.PixelFormat != PixelFormat.Format8bppIndexed )

                   throw new ArgumentException( );

 

              // get palette

              ColorPalette cp = srcImg.Palette;

              // init palette

              for ( int i = 0; i < 256; i++ )

              {

                   cp.Entries[i] = Color.FromArgb( i, i, i );

              }

              // set palette back

              srcImg.Palette = cp;

         }//#

/*********************************END********************************************/

阅读(2715) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册