资源预览内容
第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
第9页 / 共16页
第10页 / 共16页
亲,该文档总共16页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
运用运用 Visual C#完成基本数字图像处理完成基本数字图像处理引言:引言: 微软的新的.NET 平台为开发者带来了许多新的诸如 GDI+、Globalization 之类的编程机制,同时还发明了一门全新的类似 Java 的编程语言C#。对于这些新知识,我们应尽快了解、掌握并试图运用到实践项目中去,而通过实例学习的方法无疑是一个非常有效的途径。本文就通过一个简单的实例,向大家展示了在 Visual C#中如何运用 GDI+和 Unsafe 代码类等技术以实现简单的数字图像处理。 一概述:一概述: 本文的实例是一个数字图像处理的应用程序,它完成的功能包括对图像颜色的翻转、对图像进行灰度处理和对图像进行增亮处理。该程序对图像进行处理部分的代码包含在一个专门的 Filters 类里面,通过调用该类里的静态成员函数,我们就可以实现相应的图像处理功能了。为实现图像处理,我们要对图像进行逐个象素处理。我们知道图像是由一个个的象素点组成的,对一幅图像的每个象素进行了相应的处理,最后整个图像也就处理好了。在这个过程中,我们只需对每个象素点进行相应的处理,在处理过程中却不需要考虑周围象素点对其的影响,所以相对来说程序的实现就变得简单多了。 由于 GDI+中的 BitmapData 类不提供对图像内部数据的直接访问的方法,我们唯一的办法就是使用指针来获得图像的内部数据,这时我们就得运用 unsafe 这个关键字来指明函数中访问图像内部数据的代码块了。在程序中,我还运用了打开文件和保存文件等选项,以使我们的辛勤劳动不付之东流。 二程序的实现:二程序的实现: 1打开 Visual Studio.net,新建一个 Visual C#的项目,在模板中选择“Windows 应用程序“即可,项目名称可自定(这里为 ImageProcessor) 。 2为使窗体能显示图像,我们需要重载窗体的 OnPaint()事件函数,在该函数中我们将一个图像绘制在程序的主窗体上,为了使窗体能显示不同尺寸大小的图像,我们还将窗体的 AutoScroll 属性设置为 true。这样,根据图像的尺寸,窗体两边就会出现相应的滚动条。该函数的实现如下: private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)Graphics g = e.Graphics;g.DrawImage(m_Bitmap, new Rectangle(this.AutoScrollPosition.X, this.AutoScrollPosition.Y,(int)(m_Bitmap.Width), (int)(m_Bitmap.Height);3给主窗体添加一个主菜单,该主菜单完成了一些基本的操作,包括“打开文件“、“保存文件“、“退出“、“翻转操作“、“灰度操作“、“增亮操作“等。前面三个操作完成图像文件的打开和保存以及程序的退出功能,相应的事件处理函数如下: private void menuItemOpen_Click(object sender, System.EventArgs e)OpenFileDialog openFileDialog = new OpenFileDialog();openFileDialog.Filter = “Bitmap 文件(*.bmp)|*.bmp|Jpeg 文件(*.jpg)|*.jpg|所有合适文件(*.bmp/*.jpg)|*.bmp/*.jpg“;openFileDialog.FilterIndex = 2 ;openFileDialog.RestoreDirectory = true ;if(DialogResult.OK = openFileDialog.ShowDialog()m_Bitmap = (Bitmap)Bitmap.FromFile(openFileDialog.FileName, false);this.AutoScroll = true;this.AutoScrollMinSize=new Size (int)(m_Bitmap.Width),(int)m_Bitmap.Height);this.Invalidate();其中,m_Bitmap 为主窗体类的一个数据成员,声明为 private System.Drawing.Bitmap m_Bitmap;(注:因为程序中用到了相关的类,所以在程序文件的开始处应添加 using System.Drawing.Imaging;)同时,在该类的构造函数中,我们必须先给它 new 一个 Bitmap 对象:m_Bitmap = new Bitmap(2,2);上述代码中的 this.Invalidate();完成主窗体的重绘工作,它调用了主窗体的 OnPaint()函数,结果就将打开的图像文件显示在主窗体上。 private void menuItemSave_Click(object sender, System.EventArgs e)SaveFileDialog saveFileDialog = new SaveFileDialog();saveFileDialog.Filter = “Bitmap 文件(*.bmp)|*.bmp|Jpeg 文件(*.jpg)|*.jpg|所有合适文件(*.bmp/*.jpg)|*.bmp/*.jpg“;saveFileDialog.FilterIndex = 1 ;saveFileDialog.RestoreDirectory = true ;if(DialogResult.OK = saveFileDialog.ShowDialog()m_Bitmap.Save(saveFileDialog.FileName);其中 m_Bitmap.Save(saveFileDialog.FileName);一句完成了图像文件的保存,正是运用了 GDI+的强大功能,我们只需这么一条简单的语句就完成了以前很大工作量的任务,所以合理运用.NET 中的新机制一定会大大简化我们的工作的。 private void menuItemExit_Click(object sender, System.EventArgs e)this.Close();接下来,三个主要操作的事件处理函数如下: private void menuItemInvert_Click(object sender, System.EventArgs e)if(Filters.Invert(m_Bitmap)this.Invalidate();private void menuItemGray_Click(object sender, System.EventArgs e)if(Filters.Gray(m_Bitmap)this.Invalidate();private void menuItemBright_Click(object sender, System.EventArgs e)Parameter dlg = new Parameter();dlg.nValue = 0;if (DialogResult.OK = dlg.ShowDialog()if(Filters.Brightness(m_Bitmap, dlg.nValue)this.Invalidate();三个函数中分别调用了相应的图像处理函数 Invert() 、Gray() 、Brightness()等三个函数。这三个函数 Filters 类中的三个类型为 public 的静态函数(含有 static 关键字) ,它们的返回值类型均是 bool 型的,根据返回值我们可以决定是否进行主窗体的重绘工作。 Invert() 、Gray() 、Brightness()等三个函数均包含在 Filters 类里面,Invert()函数的算法如下: public static bool Invert(Bitmap b)BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);int stride = bmData.Stride;System.IntPtr Scan0 = bmData.Scan0;unsafebyte * p = (byte *)(void *)Scan0;int nOffset = stride - b.Width*3;int nWidth = b.Width * 3;for(int y=0;y 255)return false;BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width,b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);int stride = bmData.Stride;System.IntPtr Scan0 = bmData.Scan0;int nVal = 0;unsafebyte * p = (byte *)(void *)Scan0;int nOffset = stride - b.Width*3;int nWidth = b.Width * 3;for(int y=0;y 255) nVal = 255;p0 = (byte)nVal;+p;p += nOffset;b.UnlockBits(bmData);return true;本函数完成的功能是对图像进行增亮处理,它比上面两个函数多了一个增亮参数nBrightness,该参数由用户输入,范围为255255。在取得了增亮参数后,函数的 unsafe 代码部分对每个象素点的不同颜色成分进行逐个处理,即在原来值的基础上加上一个增亮参数以获得新的值。同时代码中还有一个防止成分值越界的操作,因为 RGB 成分值的范围为 0255,一旦超过了这个范围就要重新设置。函数最后执行成功后,同样得返回 true 值。 该函数实现的程序效果如下: 首先,我们把图像增亮的参数设置为 100(其范围为255255) ,然后执行效果如下,读者也可尝试其他的参数值。 (处理前) (处理后) 三小结:三小结: 本文通过一个简单的实例向大家展现了用 Visual C#以及 GDI+完成数字图像处理的基本方法,通过实例,我们不难发现合理运用新技术不仅可以大大简化我们的编程工作,还可以提高编程的效率。不过我们在运用新技术的同时也得明白掌握基本的编程思想才是最主要的,不同的语言、不同的机制只是实现的具体方式不同而已,其内在的思想还是相通的。对于上面的例子,掌握了编写图像处理函数的算法,用其他的方式实现也应该是可行的。同时,在上面的基础上,读者不妨试着举一反三,编写出更多的图像处理的函数来,以充实并完善这个简单的实例。 附带的源代码文件为:ImageProcessor.rar Powered by DvNews.net
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号