c#图像灰度处理中关于生成灰度图像的问题

我是参照《C#数字图像处理算法典型实例》里面的代码进行处理的,用的是内存法处理打开的图像。但经过灰度处理的图像对象怎么得到呢?我想利用得到的图像进行处理,但处理的还是原来的图像,就算我保存当前的灰度图像,打开进行处理时依然是彩色图像的性质。

代码如下

//打开图片
private void open_Click(object sender, EventArgs e)
        {
            OpenFileDialog opnDlg = new OpenFileDialog();
            opnDlg.Filter = "所有图像|*.bmp;*.pcx;*.png;*.jpg;*.gif;|" + "位图(*.bmp)|*.bmp;*.jpg;*.png|" + "矢量图|*.wmf;*.eps;*.emf";
            opnDlg.Title = "打开图片";
            opnDlg.ShowHelp = true;
            if (opnDlg.ShowDialog() == DialogResult.OK)
            {
                curName = opnDlg.FileName;
                try
                {
                    curBitmap = (Bitmap)Image.FromFile(curName);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                Invalidate();
            }

        }

//图片灰度化
private void huidu_Click(object sender, EventArgs e)
        {
            //位图矩形
            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);
            //把新生成的灰度图像赋值个curBitmap不然仍然会用原来的彩色图像来处理

            //对窗体进行重新绘制
            Invalidate();
        }


//保存图片
private void save_Click(object sender, EventArgs e)
        {
            if (curBitmap!=null)
            {
                SaveFileDialog sfd = new SaveFileDialog();
                sfd.Title = "保存为";
                sfd.OverwritePrompt = true;
                sfd.Filter = "BMP文件|*.bmp";
                sfd.ShowHelp = true;
                if (sfd.ShowDialog()==DialogResult.OK)
                {
                    string fileName = sfd.FileName;
                    string strFileExtn = fileName.Remove(0, fileName.Length - 3);

                    //保存文件
                    switch (strFileExtn)
                    {
                        case"bmp":
                            curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Bmp);
                            break;
                        default:
                            break;
                    }
                }
            }
        }

//绘制图片
private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            if (curBitmap != null)
            {
                g.DrawImage(curBitmap, 160, 20, curBitmap.Width, curBitmap.Height);

            }
        }

3个回答

在窗体上添加一个PictureBox,执行灰度处理后,设置到PictureBox,看一下效果,是不是算法有问题。

asasaas121
asasaas121 我不只是要灰度化还需要对图像进行处理,但通过灰度化得到的图像的bmpdata对象里面的width和stride不一样,这样在处理滤波时就会出错
5 年多之前 回复
 static void Main(string[] args)
{
  Bitmap bitmap = new Bitmap(Environment.CurrentDirectory + "//1.jpg");

  for (int i = 0; i < bitmap.Width; i++)
  {
    for (int j = 0; j < bitmap.Height; j++)
    {
      //取图片当前的像素点
      var color = bitmap.GetPixel(i, j);

      var gray = (int)(color.R * 0.299 + color.G * 0.587 + color.B * 0.114);

      //重新设置当前的像素点
      bitmap.SetPixel(i, j, Color.FromArgb(gray, gray, gray));
    }
  }

  bitmap.Save(Environment.CurrentDirectory + "//2.jpg");
}
asasaas121
asasaas121 灰度化没有问题,图片都能作为灰度图像,但是一般的灰度图像width和stride不一样,还是有3个色道
5 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐