1. 程式人生 > >24位bmp影象轉成灰度影象

24位bmp影象轉成灰度影象

  private void 灰度轉換ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                //點陣圖矩形,0, 0, curBitmap.Width, curBitmap.Height分別表示左上角x,y座標,矩形寬度,高度。
                Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                //以可讀寫的方式鎖定全部點陣圖畫素
                System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                //得到首地址
                IntPtr ptr = bmpData.Scan0;

                //定義被鎖定的陣列大小,由點陣圖資料與未用空間組成
                int bytes = bmpData.Stride*bmpData.Height;
                byte[] rgbValues = new byte[bytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

                //灰度化
                double colorTemp = 0;
                for(int i=0;i<bmpData.Height;i++)
                { 
                    //只處理每行中是影象畫素的資料,捨棄未用空間
                    for (int j = 0; j < bmpData.Width * 3; j += 3)
                    {
                        colorTemp = rgbValues[i * bmpData.Stride + j + 2] * 0.299 +
                            rgbValues[i * bmpData.Stride + j + 1] * 0.587+
                            rgbValues[i * bmpData.Stride + j ] * 0.114;
                        rgbValues[i*bmpData.Stride+j]=rgbValues[i*bmpData.Stride+j+1]=rgbValues[i*bmpData.Stride+j+2]=(byte)colorTemp;
                    }

                }
                
                //把陣列複製回點陣圖
                System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
                // 解鎖點陣圖畫素
                curBitmap.UnlockBits(bmpData);
                //對窗體進行重新繪製,這將強制執行Paint事件處理程式
                Invalidate();
            }