源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

浅谈Visual C#进行图像处理(读取、保存以及对像素的访问)

  • 时间:2022-08-10 00:28 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:浅谈Visual C#进行图像处理(读取、保存以及对像素的访问)
这里之所以说“浅谈”是因为我这里只是简单的介绍如何使用Visual C#进行图像的读入、保存以及对像素的访问。而不涉及太多的算法。 [b]一、读取图像[/b] 在Visual C#中我们可以使用一个Picture Box控件来显示图片,如下:
[u]复制代码[/u] 代码如下:
private void btnOpenImage_Click(object sender, EventArgs e) {     OpenFileDialog ofd = new OpenFileDialog();     ofd.Filter = "BMP Files(*.bmp)|*.bmp|JPG Files(*.jpg;*.jpeg)|*.jpg;*.jpeg|All Files(*.*)|*.*";     ofd.CheckFileExists = true;     ofd.CheckPathExists = true;     if (ofd.ShowDialog() == DialogResult.OK)     {         //pbxShowImage.ImageLocation = ofd.FileName;         bmp = new Bitmap(ofd.FileName);         if (bmp==null)         {             MessageBox.Show("加载图片失败!", "错误");             return;         }         pbxShowImage.Image = bmp;         ofd.Dispose();     } }
其中bmp为类的一个对象:private Bitmap bmp=null; 在使用Bitmap类和BitmapData类之前,需要使用using System.Drawing.Imaging; [b]二、保存图像[/b]
[u]复制代码[/u] 代码如下:
private void btnSaveImage_Click(object sender, EventArgs e) {     if (bmp == null) return;     SaveFileDialog sfd = new SaveFileDialog();     sfd.Filter = "BMP Files(*.bmp)|*.bmp|JPG Files(*.jpg;*.jpeg)|*.jpg;*.jpeg|All Files(*.*)|*.*";     if (sfd.ShowDialog() == DialogResult.OK)     {         pbxShowImage.Image.Save(sfd.FileName);         MessageBox.Show("保存成功!","提示");         sfd.Dispose();     } }
[b]三、对像素的访问[/b] 我们可以来建立一个GrayBitmapData类来做相关的处理。整个类的程序如下:
[u]复制代码[/u] 代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms; namespace ImageElf {     class GrayBitmapData     {         public byte[,] Data;//保存像素矩阵         public int Width;//图像的宽度         public int Height;//图像的高度         public GrayBitmapData()         {             this.Width = 0;             this.Height = 0;             this.Data = null;         }         public GrayBitmapData(Bitmap bmp)         {             BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);             this.Width = bmpData.Width;             this.Height = bmpData.Height;             Data = new byte[Height, Width];             unsafe             {                 byte* ptr = (byte*)bmpData.Scan0.ToPointer();                 for (int i = 0; i < Height; i++)                 {                     for (int j = 0; j < Width; j++)                     {     //将24位的RGB彩色图转换为灰度图                         int temp = (int)(0.114 * (*ptr++)) + (int)(0.587 * (*ptr++))+(int)(0.299 * (*ptr++));                         Data[i, j] = (byte)temp;                     }                     ptr += bmpData.Stride - Width * 3;//指针加上填充的空白空间                 }             }             bmp.UnlockBits(bmpData);         }         public GrayBitmapData(string path)             : this(new Bitmap(path))         {         }         public Bitmap ToBitmap()         {             Bitmap bmp=new Bitmap(Width,Height,PixelFormat.Format24bppRgb);             BitmapData bmpData=bmp.LockBits(new Rectangle(0,0,Width,Height),ImageLockMode.WriteOnly,PixelFormat.Format24bppRgb);             unsafe             {                 byte* ptr=(byte*)bmpData.Scan0.ToPointer();                 for(int i=0;i<Height;i++)                 {                     for(int j=0;j<Width;j++)                     {                         *(ptr++)=Data[i,j];                         *(ptr++)=Data[i,j];                         *(ptr++)=Data[i,j];                     }                     ptr+=bmpData.Stride-Width*3;                 }             }             bmp.UnlockBits(bmpData);             return bmp;         }         public void ShowImage(PictureBox pbx)         {             Bitmap b = this.ToBitmap();             pbx.Image = b;             //b.Dispose();         }         public void SaveImage(string path)         {             Bitmap b=ToBitmap();             b.Save(path);             //b.Dispose();         } //均值滤波         public void AverageFilter(int windowSize)         {             if (windowSize % 2 == 0)             {                 return;             }             for (int i = 0; i < Height; i++)             {                 for (int j = 0; j < Width; j++)                 {                     int sum = 0;                     for (int g = -(windowSize - 1) / 2; g <= (windowSize - 1) / 2; g++)                     {                         for (int k = -(windowSize - 1) / 2; k <= (windowSize - 1) / 2; k++)                         {                             int a = i + g, b = j + k;                             if (a < 0) a = 0;                             if (a > Height - 1) a = Height - 1;                             if (b < 0) b = 0;                             if (b > Width - 1) b = Width - 1;                             sum += Data[a, b];                         }                     }                     Data[i,j]=(byte)(sum/(windowSize*windowSize));                 }             }         } //中值滤波         public void MidFilter(int windowSize)         {             if (windowSize % 2 == 0)             {                 return;             }             int[] temp = new int[windowSize * windowSize];             byte[,] newdata = new byte[Height, Width];             for (int i = 0; i < Height; i++)             {                 for (int j = 0; j < Width; j++)                 {                     int n = 0;                     for (int g = -(windowSize - 1) / 2; g <= (windowSize - 1) / 2; g++)                     {                         for (int k = -(windowSize - 1) / 2; k <= (windowSize - 1) / 2; k++)                         {                             int a = i + g, b = j + k;                             if (a < 0) a = 0;                             if (a > Height - 1) a = Height - 1;                             if (b < 0) b = 0;                             if (b > Width - 1) b = Width - 1;                             temp[n++]= Data[a, b];                         }                     }                     newdata[i, j] = GetMidValue(temp,windowSize*windowSize);                 }             }             for (int i = 0; i < Height; i++)             {                 for (int j = 0; j < Width; j++)                 {                     Data[i, j] = newdata[i, j];                 }             }         } //获得一个向量的中值         private byte GetMidValue(int[] t, int length)         {             int temp = 0;             for (int i = 0; i < length - 2; i++)             {                 for (int j = i + 1; j < length - 1; j++)                 {                     if (t[i] > t[j])                     {                         temp = t[i];                         t[i] = t[j];                         t[j] = temp;                     }                 }             }             return (byte)t[(length - 1) / 2];         } //一种新的滤波方法,是亮的更亮、暗的更暗         public void NewFilter(int windowSize)         {             if (windowSize % 2 == 0)             {                 return;             }             for (int i = 0; i < Height; i++)             {                 for (int j = 0; j < Width; j++)                 {                     int sum = 0;                     for (int g = -(windowSize - 1) / 2; g <= (windowSize - 1) / 2; g++)                     {                         for (int k = -(windowSize - 1) / 2; k <= (windowSize - 1) / 2; k++)                         {                             int a = i + g, b = j + k;                             if (a < 0) a = 0;                             if (a > Height - 1) a = Height - 1;                             if (b < 0) b = 0;                             if (b > Width - 1) b = Width - 1;                             sum += Data[a, b];                         }                     }                     double avg = (sum+0.0) / (windowSize * windowSize);                     if (avg / 255 < 0.5)                     {                         Data[i, j] = (byte)(2 * avg / 255 * Data[i, j]);                     }                     else                     {                         Data[i,j]=(byte)((1-2*(1-avg/255.0)*(1-Data[i,j]/255.0))*255);                     }                 }             }         } //直方图均衡         public void HistEqual()         {             double[] num = new double[256] ;             for(int i=0;i<256;i++) num[i]=0;             for (int i = 0; i < Height; i++)             {                 for (int j = 0; j < Width; j++)                 {                     num[Data[i, j]]++;                 }             }             double[] newGray = new double[256];             double n = 0;             for (int i = 0; i < 256; i++)             {                 n += num[i];                 newGray[i] = n * 255 / (Height * Width);             }             for (int i = 0; i < Height; i++)             {                 for (int j = 0; j < Width; j++)                 {                     Data[i,j]=(byte)newGray[Data[i,j]];                 }             }         } } }
在GrayBitmapData类中,只要我们对一个二维数组Data进行一系列的操作就是对图片的操作处理。在窗口上,我们可以使用 一个按钮来做各种调用:
[u]复制代码[/u] 代码如下:
//均值滤波 private void btnAvgFilter_Click(object sender, EventArgs e) {     if (bmp == null) return;     GrayBitmapData gbmp = new GrayBitmapData(bmp);     gbmp.AverageFilter(3);     gbmp.ShowImage(pbxShowImage); } //转换为灰度图 private void btnToGray_Click(object sender, EventArgs e) {     if (bmp == null) return;     GrayBitmapData gbmp = new GrayBitmapData(bmp);     gbmp.ShowImage(pbxShowImage); }
[b]四、总结[/b] 在Visual c#中对图像进行处理或访问,需要先建立一个Bitmap对象,然后通过其LockBits方法来获得一个BitmapData类的对象,然后通过获得其像素数据的首地址来对Bitmap对象的像素数据进行操作。当然,一种简单但是速度慢的方法是用Bitmap类的GetPixel和SetPixel方法。其中BitmapData类的Stride属性为每行像素所占的字节。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部