




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、运用Visual C#完成基本数字图像处理引言: 微软的新的.NET平台为开发者带来了许多新的诸如GDI+、Globalization之类的编程机制,同时还发明了一门全新的类似Java的编程语言C#。对于这些新知识,我们应尽快了解、掌握并试图运用到实践项目中去,而通过实例学习的方法无疑是一个非常有效的途径。本文就通过一个简单的实例,向大家展示了在Visual C#中如何运用GDI+和Unsafe代码类等技术以实现简单的数字图像处理。 一概述: 本文的实例是一个数字图像处理的应用程序,它完成的功能包括对图像颜色的翻转、对图像进行灰度处理和对图像进行增亮处理。该程序对图像进行处理部分的代码包含在一
2、个专门的Filters类里面,通过调用该类里的静态成员函数,我们就可以实现相应的图像处理功能了。为实现图像处理,我们要对图像进行逐个象素处理。我们知道图像是由一个个的象素点组成的,对一幅图像的每个象素进行了相应的处理,最后整个图像也就处理好了。在这个过程中,我们只需对每个象素点进行相应的处理,在处理过程中却不需要考虑周围象素点对其的影响,所以相对来说程序的实现就变得简单多了。 由于GDI+中的BitmapData类不提供对图像内部数据的直接访问的方法,我们唯一的办法就是使用指针来获得图像的内部数据,这时我们就得运用unsafe这个关键字来指明函数中访问图像内部数据的代码块了。在程序中,我还运用
3、了打开文件和保存文件等选项,以使我们的辛勤劳动不付之东流。 二程序的实现: 1打开Visual S,新建一个Visual C#的项目,在模板中选择"Windows 应用程序"即可,项目名称可自定(这里为ImageProcessor)。 2为使窗体能显示图像,我们需要重载窗体的OnPaint()事件函数,在该函数中我们将一个图像绘制在程序的主窗体上,为了使窗体能显示不同尺寸大小的图像,我们还将窗体的AutoScroll属性设置为true。这样,根据图像的尺寸,窗体两边就会出现相应的滚动条。该函数的实现如下: private void Form1_Paint(object se
4、nder, 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给主窗体添加一个主菜单,该主菜单完成了一些基本的操作,包括"打开文件"、"保存文件"、"退出"、"翻转操作"
5、;、"灰度操作"、"增亮操作"等。前面三个操作完成图像文件的打开和保存以及程序的退出功能,相应的事件处理函数如下: private void menuItemOpen_Click(object sender, System.EventArgs e) OpenFileDialog openFileDialog = new OpenFileDialog();openFileDialog.Filter = "Bitmap文件(*.bmp)|*.bmp| Jpeg文件(*.jpg)|*.jpg| 所有合适文件(*.bmp/*.jpg)|*.bmp/*.
6、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);
7、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 menuIte
8、mSave_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.O
9、K = 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();接下来,三个主要操作的事件处理函数如下: pri
10、vate 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
11、 = 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(
12、)等三个函数均包含在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
13、;int nOffset = stride - b.Width*3;int nWidth = b.Width * 3;for(int y=0;y<b.Height;+y)for(int x=0; x < nWidth; +x )p0 = (byte)(255-p0);+p;p += nOffset;b.UnlockBits(bmData);return true; 该函数以及后面的函数的参数都是Bitmap类型的,它们传值的对象就是程序中所打开的图像文件了。该函数中的BitmapData类型的bmData包含了图像文件的内部信息,bmData的Stride属性指明了一条线的宽度,而
14、它的Scan0属性则是指向图像内部信息的指针。本函数完成的功能是图像颜色的翻转,实现的方法即用255减去图像中的每个象素点的值,并将所得值设置为原象素点处的值,对每个象素点进行如此的操作,只到整幅图像都处理完毕。函数中的unsafe代码块是整个函数的主体部分,首先我们取得图像内部数据的指针,然后设置好偏移量,同时设置nWidth为b.Width*3,因为每个象素点包含了三种颜色成分,对每个象素点进行处理时便要进行三次处理。接下来运用两个嵌套的for循环完成对每个象素点的处理,处理的核心便是一句:p0 = (byte)(255-p0);。在unsafe代码块后,便可运用b.UnlockBits(
15、bmData)进行图像资源的释放。函数执行成功,最后返回true值。注:由于是要编译不安全代码,所以得将项目属性页中的"允许不安全代码块"属性设置为true,图示如下: 该函数实现的程序效果如下: (处理前) (处理后) Gray()函数的算法如下: public static bool Gray(Bitmap b) BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);int st
16、ride = bmData.Stride;System.IntPtr Scan0 = bmData.Scan0;unsafebyte * p = (byte *)(void *)Scan0;int nOffset = stride - b.Width*3;byte red, green, blue;for(int y=0;y<b.Height;+y) for(int x=0; x < b.Width; +x ) blue = p0; green = p1; red = p2; p0 = p1 = p2 = (byte)(.299 * red + .587 * green + .11
17、4 * blue); p += 3; p += nOffset;b.UnlockBits(bmData);return true; 本函数完成的功能是对图像进行灰度处理,我们的基本想法可是将每个象素点的三种颜色成分的值取平均值。然而由于人眼的敏感性,这样完全取平均值的做法的效果并不好,所以在程序中我取了三个效果最好的参数:.299,.587,.114。不过在这里要向读者指明的是,在GDI+中图像存储的格式是BGR而非RGB,即其顺序为:Blue、Green、Red。所以在for循环内部一定要设置好red、green、blue等变量的值,切不可颠倒。函数执行成功后,同样返回true值。 该函数实
18、现的程序效果如下: (处理前) (处理后) Brightness()函数的算法如下: public static bool Brightness(Bitmap b, int nBrightness)if (nBrightness < -255 | nBrightness > 255)return false;BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);int stride = bm
19、Data.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<b.Height;+y) for(int x=0; x < nWidth; +x ) nVal = (int) (p0 + nBrightness);if (nVal < 0) nVal = 0;if (nVal > 255) nVal = 255;p0 = (byte)nVal;+p;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025版型钢结构瓦工施工总承包合同
- 2025版沙盘模型制作技术培训及转让合同
- 2025版新能源汽车充电站运营维护专业服务合同
- 2025版外卖配送服务合同技术升级范本
- 2025场环保产业调研与可持续发展服务协议
- 2025代收代缴水电费及环保监测服务合同
- 2025年商铺认筹与商业综合体合作框架协议
- 2025年度幼儿园食堂安全卫生管理服务协议
- 2025年度绿色建筑劳务分包合同示范文本大全
- 2025版智慧桥梁建设劳务分包合同模板
- 2025届广东省深圳市罗湖区英语八年级第二学期期末教学质量检测试题含答案
- 期权开户考试题及答案
- 建筑工程装饰预算课件
- 《民营经济促进法》解读与案例分析课件
- 山地绿化工程的安全防范措施
- 监理挂靠合同协议书
- 2025年广西南宁宾阳县昆仑投资集团有限公司招聘笔试参考题库含答案解析
- 2025-2030中国公路养护行业市场深度调研及前景趋势与投资研究报告
- 《数据采集与分析》课件
- 国家生物安全法课件
- 老年人生命教育
评论
0/150
提交评论