精品运用VisualC完成基本数字图像处理Word文档格式.docx
《精品运用VisualC完成基本数字图像处理Word文档格式.docx》由会员分享,可在线阅读,更多相关《精品运用VisualC完成基本数字图像处理Word文档格式.docx(12页珍藏版)》请在冰豆网上搜索。
X,this。
AutoScrollPosition.Y,
(int)(m_Bitmap.Width),(int)(m_Bitmap。
Height)));
}
3.给主窗体添加一个主菜单,该主菜单完成了一些基本的操作,包括”打开文件”、"
保存文件”、"
退出"
、"
翻转操作”、"
灰度操作”、”增亮操作”等.前面三个操作完成图像文件的打开和保存以及程序的退出功能,相应的事件处理函数如下:
privatevoidmenuItemOpen_Click(objectsender,System。
EventArgse)
{
OpenFileDialogopenFileDialog=newOpenFileDialog();
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=newSize((int)(m_Bitmap。
Width),(int)
m_Bitmap.Height));
Invalidate();
}
}
其中,m_Bitmap为主窗体类的一个数据成员,声明为privateSystem.Drawing.Bitmapm_Bitmap;
(注:
因为程序中用到了相关的类,所以在程序文件的开始处应添加usingSystem。
Drawing。
Imaging;
)同时,在该类的构造函数中,我们必须先给它new一个Bitmap对象:
m_Bitmap=newBitmap(2,2);
上述代码中的this.Invalidate();
完成主窗体的重绘工作,它调用了主窗体的OnPaint()函数,结果就将打开的图像文件显示在主窗体上。
privatevoidmenuItemSave_Click(objectsender,System。
SaveFileDialogsaveFileDialog=newSaveFileDialog();
saveFileDialog.Filter="
Bitmap文件(*.bmp)|*。
bmp|
Jpeg文件(*.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中的新机制一定会大大简化我们的工作的。
privatevoidmenuItemExit_Click(objectsender,System.EventArgse)
{
this。
Close();
接下来,三个主要操作的事件处理函数如下:
privatevoidmenuItemInvert_Click(objectsender,System.EventArgse)
if(Filters。
Invert(m_Bitmap))
this.Invalidate();
}
privatevoidmenuItemGray_Click(objectsender,System.EventArgse)
{
if(Filters。
Gray(m_Bitmap))
this.Invalidate();
privatevoidmenuItemBright_Click(objectsender,System。
Parameterdlg=newParameter();
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()函数的算法如下:
publicstaticboolInvert(Bitmapb)
BitmapDatabmData=b。
LockBits(newRectangle(0,0,b.Width,b。
Height),
ImageLockMode。
ReadWrite,PixelFormat.Format24bppRgb);
intstride=bmData.Stride;
System。
IntPtrScan0=bmData.Scan0;
unsafe
byte*p=(byte*)(void*)Scan0;
intnOffset=stride-b。
Width*3;
intnWidth=b.Width*3;
for(inty=0;
y〈b。
Height;
++y)
for(intx=0;
x〈nWidth;
++x)
{
p[0]=(byte)(255-p[0]);
++p;
}
p+=nOffset;
b.UnlockBits(bmData);
returntrue;
该函数以及后面的函数的参数都是Bitmap类型的,它们传值的对象就是程序中所打开的图像文件了。
该函数中的BitmapData类型的bmData包含了图像文件的内部信息,bmData的Stride属性指明了一条线的宽度,而它的Scan0属性则是指向图像内部信息的指针.本函数完成的功能是图像颜色的翻转,实现的方法即用255减去图像中的每个象素点的值,并将所得值设置为原象素点处的值,对每个象素点进行如此的操作,只到整幅图像都处理完毕。
函数中的unsafe代码块是整个函数的主体部分,首先我们取得图像内部数据的指针,然后设置好偏移量,同时设置nWidth为b。
Width*3,因为每个象素点包含了三种颜色成分,对每个象素点进行处理时便要进行三次处理。
接下来运用两个嵌套的for循环完成对每个象素点的处理,处理的核心便是一句:
p[0]=(byte)(255—p[0]);
。
在unsafe代码块后,便可运用b.UnlockBits(bmData)进行图像资源的释放。
函数执行成功,最后返回true值。
注:
由于是要编译不安全代码,所以得将项目属性页中的"
允许不安全代码块”属性设置为true,图示如下:
该函数实现的程序效果如下:
(处理前)
(处理后)
Gray()函数的算法如下:
publicstaticboolGray(Bitmapb)
BitmapDatabmData=b.LockBits(newRectangle(0,0,b。
Width,b.Height),
ImageLockMode.ReadWrite,PixelFormat。
Format24bppRgb);
intstride=bmData。
Stride;
System。
IntPtrScan0=bmData.Scan0;
byte*p=(byte*)(void*)Scan0;
Width*3;
bytered,green,blue;
Height;
for(intx=0;
x〈b.Width;
blue=p[0];
green=p[1];
red=p[2];
p[0]=p[1]=p[2]=(byte)(。
299*red+。
587*green+.114*blue);
p+=3;
p+=nOffset;
b。
UnlockBits(bmData);
本函数完成的功能是对图像进行灰度处理,我们的基本想法可是将每个象素点的三种颜色成分的值取平均值。
然而由于人眼的敏感性,这样完全取平均值的做法的效果并不好,所以在程序中我取了三个效果最好的参数:
.299,.587,。
114.不过在这里要向读者指明的是,在GDI+中图像存储的格式是BGR而非RGB,即其顺序为:
Blue、Green、Red.所以在for循环内部一定要设置好red、green、blue等变量的值,切不可颠倒。
函数执行成功后,同样返回true值.
Brightness()函数的算法如下:
publicstaticboolBrightness(Bitmapb,intnBrightness)
if(nBrightness<
—255||nBrightness>
255)
returnfalse;
BitmapDatabmData=b。
LockBits(newRectangle(0,0,b.Width,
b.Height),ImageLockMode。
ReadWrite,
PixelFormat。
Format24bppRgb);
intstride=bmData。
System。
IntPtrScan0=bmData。
Scan0;
intnVal=0;
unsafe
byte*p=(byte*)(void*)Scan0;
intnOffset=stride—b。
Width*3;
intnWidth=b.Width*3;
for(inty=0;
y〈b.Height;
{
nVal=(int)(p[0]+nBrightness);
if(nVal〈0)nVal=0;
if(nVal>
255)nVal=255;
p[0]=(byte)nVal;
++p;
}
b。
UnlockBits(bmData);
returntrue;
本函数完成的功能是对图像进行增亮处理,它比上面两个函数多了一个增亮参数-nBrightness,该参数由用户输入,范围为-255~255.在取得了增亮参数后,函数的unsafe代码部分对每个象素点的不同颜色成分进行逐个处理,即在原来值的基础上加上一个增亮参数以获得新的值.同时代码中还有一个防止成分值越界的操作,因为RGB成分值的范围为0~255,一旦超过了这个范围就要重新设置。
函数最后执行成功后,同样得返回true值。
首先,我们把图像增亮的参数设置为100(其范围为-255~255),然后执行效果如下,读者也可尝试其他的参数值。
三.小结:
本文通过一个简单的实例向大家展现了用VisualC#以及GDI+完成数字图像处理的基本方法,通过实例,我们不难发现合理运用新技术不仅可以大大简化我们的编程工作,还可以提高编程的效率。
不过我们在运用新技术的同时也得明白掌握基本的编程思想才是最主要的,不同的语言、不同的机制只是实现的具体方式不同而已,其内在的思想还是相通的。
对于上面的例子,掌握了编写图像处理函数的算法,用其他的方式实现也应该是可行的。
同时,在上面的基础上,读者不妨试着举一反三,编写出更多的图像处理的函数来,以充实并完善这个简单的实例.
附带的源代码文件为:
ImageProcessor。
rar
PoweredbyDvNews。
net