利用Visual C#处理数字图像1

转载 2007年09月21日 23:20:00
更新时间:2005-09-30 09:55
关 键 词:C#
阅读提示:本文通过一个简单的实例向大家展现了用Visual C#以及GDI+完成数字图像处理的基本方法

 

本文就通过一个简单的实例,向大家展示了在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;

unsafe

{

byte * p = (byte *)(void *)Scan0;

int nOffset = stride - b.Width*3;

int nWidth = b.Width * 3;

for(int y=0;y
{

for(int x=0; x < nWidth; ++x )

{

p[0] = (byte)(255-p[0]);

++p;

}

p += nOffset;

}

}

b.UnlockBits(bmData);

return true;

}

该函数以及后面的函数的参数都是Bitmap类型的,它们传值的对象就是程序中所打开的图像文件了。该函数中的BitmapData类型的bmData包含了图像文件的内部信息,bmData的Stride属性指明了一条线的宽度,而它的Scan0属性则是指向图像内部信息的指针。本函数完成的功能是图像颜色的翻转,实现的方法即用255减去图像中的每个象素点的值,并将所得值设置为原象素点处的值,对每个象素点进行如此的操作,只到整幅图像都处理完毕。函数中的unsafe代码块是整个函数的主体部分,首先我们取得图像内部数据的指针,然后设置好偏移量,同时设置nWidth为b.Width*3,因为每个象素点包含了三种颜色成分,对每个象素点进行处理时便要进行三次处理。接下来运用两个嵌套的for循环完成对每个象素点的处理,处理的核心便是一句:p[0] = (byte)(255-p[0]);。在unsafe代码块后,便可运用b.UnlockBits(bmData)进行图像资源的释放。函数执行成功,最后返回true值。

 

visual C++数字图像处理类

由于现在手头的学习是关于图像处理的,有些技能肯定迟早要用上,于是决定利用假期学习Visual C++的相关知识。 今天是第一天,主要学习使用visual c++进行面向对象编程的基本方法。并给出数字...
  • a1154761720
  • a1154761720
  • 2015年01月21日 22:53
  • 1717

Win8 Metro(C#)数字图像处理--2.50图像运动模糊

 [函数名称]   图像运动模糊算法    MotionblurProcess(WriteableBitmap src,int k,int direction) [算法说明]   运动模糊...
  • Trent1985
  • Trent1985
  • 2015年04月17日 13:39
  • 1357

国内外数字图像处理网站

Visual Communications Lab University of Southern California Signal and Image Processing Institute ...
  • gfire2008
  • gfire2008
  • 2014年06月27日 09:09
  • 752

《数字图像处理与机器视觉——Visual C++与Matlab实现》知识要点总结

第0~2章介绍了数字图像处理的基础知识和编程基础。 第3~4章分别介绍了图像的灰度变换和几何变换。通过灰度变换可以有效地改善图像的外观,并在一定程度上实现图像的灰度归一化;几何变换则主要应用在图像的...
  • jelly_on_the_way
  • jelly_on_the_way
  • 2017年03月02日 11:28
  • 709

数字图像处理初学者学习路线

经历了半年多的学习,图像处理总算入门了,做了个小项目,将之前所学的都用到了。虽不敢说精通,但该掌握的工具都掌握了,包括图像算法。图像处理虽说不难,但刚开始入门,还是不易的,我也走了不少弯路,希望借鉴给...
  • qq_23225317
  • qq_23225317
  • 2016年10月25日 16:58
  • 2024

c# 数字图像处理的一些方法

最近在写小论文,涉及一些图像处理方面的代码,许久没有写过博客了,论文发了没事就来发点。 代码也不全是自己写的,参考了很多网上和书上的,就在此做个整理吧。。。...
  • baidu_31981559
  • baidu_31981559
  • 2016年05月20日 16:01
  • 1397

C#数字图像处理<一>

C#数字图像处理基础 Bitmap类,BitmapData类和Graph
  • u013488148
  • u013488148
  • 2014年09月26日 10:07
  • 1016

【转】Visual C++/MFC数字图像处理学习参考资料下载大全

http://ishare.iask.sina.com.cn/f/9590248.html?from=like Visual C++数字图像处理典型算法及实现(光盘).rar ******...
  • yf0811240333
  • yf0811240333
  • 2014年07月25日 10:39
  • 916

数字图像处理中的基本图像类型

数字图像处理是通过计算机对图像进行去除噪声、增强、复原、分割、提取特征等处理的方法和技术。在计算机中,按照颜色和灰度的多少可以将图像争为二值图像、灰度图像、索引图像和真彩色RGB图像四种基本类型。目前...
  • heyuchang666
  • heyuchang666
  • 2016年09月20日 18:34
  • 1425

[数字图像处理]频域滤波(2)--高通滤波器,带阻滤波器与陷波滤波器

1.高通滤波器        首先,对一副图像进行如下二维傅里叶变换。 我们将u=0和v=0带上式,我们可以得到如下式子。 根据上式,可以到F(0,0)的值是非常大的。这里,我们...
  • thnh169
  • thnh169
  • 2013年12月08日 18:02
  • 14340
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用Visual C#处理数字图像1
举报原因:
原因补充:

(最多只允许输入30个字)