C#图像处理Word下载.docx
《C#图像处理Word下载.docx》由会员分享,可在线阅读,更多相关《C#图像处理Word下载.docx(14页珍藏版)》请在冰豆网上搜索。
三.Graphics类
Graphics对象是GDI+的关键所在,许多对象都是由Graphics类表示的,该类定义了绘制和填充图形对象的方法和属性,一个应用程序只要需要进行绘制或着色,它就必须使用Graphics对象.
四.Image类
这个类提供了位图和元文件操作的函数.Image类被声明为abstract,也就是说Image类不能实例化对象,而只能做为一个基类.
1.FromFile方法:
它根据输入的文件名产生一个Image对象,它有两种函数形式:
publicstaticImageFromFile(stringfilename);
publicstaticImageFromFile(stringfilename,booluseEmbeddedColorManagement);
2.FromHBitmap方法:
它从一个windows句柄处创建一个bitmap对象,它也包括两种函数形式:
publicstaticbitmapfromhbitmap(intptrhbitmap);
publicstaticbitmapfromhbitmap(intptrhbitmap,intptrhpalette);
3.FromStream方法:
从一个数据流中创建一个image对象,它包含三种函数形式:
publicstaticimagefromstream(streamstream);
publicstaticimagefromstream(streamstream,booluseembeddedcolormanagement);
fromstream(streamstream,booluseembeddedcolormanagement,boolvalidateimagedata);
有了上面的了解,我们便可以开始利用C#做图像处理,下面介绍几种方法:
一.打开、保存、显示图像
privateBitmapsrcBitmap=null;
privateBitmapshowBitmap=null;
//打开文件
privatevoidmenuFileOpen_Click(objectsender,EventArgse)
{
OpenFileDialogopenFileDialog=newOpenFileDialog();
openFileDialog.Filter=@"
Bitmap文件(*.bmp)|*.bmp|Jpeg文件(*.jpg)|*.jpg|所有合适文件(*.bmp,*.jpg)|*.bmp;
*.jpg"
;
openFileDialog.FilterIndex=3;
openFileDialog.RestoreDirectory=true;
if(DialogResult.OK==openFileDialog.ShowDialog())
srcBitmap=(Bitmap)Bitmap.FromFile(openFileDialog.FileName,false);
showBitmap=srcBitmap;
this.AutoScroll=true;
this.AutoScrollMinSize=newSize((int)(showBitmap.Width),(int)(showBitmap.Height));
this.Invalidate();
}
//保存图像文件
privatevoidmenuFileSave_Click(objectsender,EventArgse)
if(showBitmap!
=null)
SaveFileDialogsaveFileDialog=newSaveFileDialog();
saveFileDialog.Filter=@"
saveFileDialog.FilterIndex=3;
saveFileDialog.RestoreDirectory=true;
if(DialogResult.OK==saveFileDialog.ShowDialog())
{
ImageFormatformat=ImageFormat.Jpeg;
switch(Path.GetExtension(saveFileDialog.FileName).ToLower())
case"
.jpg"
:
format=ImageFormat.Jpeg;
break;
.bmp"
format=ImageFormat.Bmp;
default:
MessageBox.Show(this,"
Unsupportedimageformatwasspecified"
"
Error"
MessageBoxButtons.OK,MessageBoxIcon.Error);
return;
try
showBitmap.Save(saveFileDialog.FileName,format);
catch(Exception)
Failedwritingimagefile"
//窗口重绘,在窗体上显示图像,重载Paint
privatevoidfrmMain_Paint(objectsender,System.Windows.Forms.PaintEventArgse)
{
Graphicsg=e.Graphics;
g.DrawImage(showBitmap,newRectangle(this.AutoScrollPosition.X,this.AutoScrollPosition.Y,
(int)(showBitmap.Width),(int)(showBitmap.Height)));
//灰度化
privatevoidmenu2Gray_Click(objectsender,EventArgse)
if(showBitmap==null)return;
showBitmap=RGB2Gray(showBitmap);
//下面都以RGB2Gray为例
二.提取像素法
这种方法简单易懂,但相当耗时,完全不可取.
publicstaticBitmapRGB2Gray(BitmapsrcBitmap)
ColorsrcColor;
intwide=srcBitmap.Width;
intheight=srcBitmap.Height;
for(inty=0;
y<
height;
y++)
for(intx=0;
x<
wide;
x++)
//获取像素的RGB颜色值
srcColor=srcBitmap.GetPixel(x,y);
bytetemp=(byte)(srcColor.R*.299+srcColor.G*.587+srcColor.B*.114);
//设置像素的RGB颜色值
srcBitmap.SetPixel(x,y,Color.FromArgb(temp,temp,temp));
returnsrcBitmap;
}//#
三.内存法
这是比较常用的方法
intheight=srcBitmap.Height;
Rectanglerect=newRectangle(0,0,wide,height);
//将Bitmap锁定到系统内存中,获得BitmapData
BitmapDatasrcBmData=srcBitmap.LockBits(rect,
ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
//创建Bitmap
BitmapdstBitmap=CreateGrayscaleImage(wide,height);
//这个函数在后面有定义
BitmapDatadstBmData=dstBitmap.LockBits(rect,
ImageLockMode.ReadWrite,PixelFormat.Format8bppIndexed);
//位图中第一个像素数据的地址。
它也可以看成是位图中的第一个扫描行
System.IntPtrsrcPtr=srcBmData.Scan0;
System.IntPtrdstPtr=dstBmData.Scan0;
//将Bitmap对象的信息存放到byte数组中
intsrc_bytes=srcBmData.Stride*height;
byte[]srcValues=newbyte[src_bytes];
intdst_bytes=dstBmData.Stride*height;
byte[]dstValues=newbyte[dst_bytes];
//复制GRB信息到byte数组
System.Runtime.InteropServices.Marshal.Copy(srcPtr,srcValues,0,src_bytes);
System.Runtime.InteropServices.Marshal.Copy(dstPtr,dstValues,0,dst_bytes);
//根据Y=0.299*R+0.114*G+0.587B,Y为亮度
for(inti=0;
i<
i++)
for(intj=0;
j<
j++)
//只处理每行中图像像素数据,舍弃未用空间
//注意位图结构中RGB按BGR的顺序存储
intk=3*j;
bytetemp=(byte)(srcValues[i*srcBmData.Stride+k+2]*.299
+srcValues[i*srcBmData.Stride+k+1]*.587+srcValues[i*srcBmData.Stride+k]*.114);
dstValues[i*dstBmData.Stride+j]=temp;
//将更改过的byte[]拷贝到原位图
System.Runtime.InteropServices.Marshal.Copy(dstValues,0,dstPtr,dst_bytes);
//解锁位图
srcBitmap.UnlockBits(srcBmData);
dstBitmap.UnlockBits(dstBmData);
returndstBitmap;
四指针法
C/C++的习惯,不是C#的特点
intheight=srcBitmap.Height;
System.IntPtrsrcScan=srcBmData.Scan0;
System.IntPtrdstScan=dstBmData.Scan0;
Unsafe//启动不安全代码
byte*srcP=(byte*)(void*)srcScan;
byte*dstP=(byte*)(void*)dstScan;
intsrcOffset=srcBmData.Stride-wide*3;
intdstOffset=dstBmData.Stride-wide;
bytered,green,blue;
wide;
x++,srcP+=3,dstP++)
blue=srcP[0];
green=srcP[1];
red=srcP[2];
*dstP=(byte)(.299*red+.587*green+.114*blue);
srcP+=srcOffset;
dstP+=dstOffset;
dstBitmap.UnlockBits(dstBmData);
五.矩阵法
并不是什么新方法,只是将图像数据分做R,G,B三个矩阵(二维数组)存储,类似MATLAB的习惯.
publicstaticboolGetRGB(BitmapSource,outint[,]R,outint[,]G,outint[,]B)
intiWidth=Source.Width;
intiHeight=Source.Height;
Rectanglerect=newRectangle(0,0,iWidth,iHeight);
System.Drawing.Imaging.BitmapDatabmpData=Source.LockBits(rect,System.Drawing.Imaging.ImageLockMode.ReadWrite,Source.PixelFormat);
IntPtriPtr=bmpData.Scan0;
intiBytes=iWidth*iHeight*3;
byte[]PixelValues=newbyte[iBytes];
System.Runtime.InteropServices.Marshal.Copy(iPtr,PixelValues,0,iBytes);
Source.UnlockBits(bmpData);
//注意这个地方图像的两维方向与数组两维的方向是转置的关系
R=newint[iHeight,iWidth];
G=newint[iHeight,iWidth];
B=newint[iHeight,iWidth];
intiPoint=0;
iHeight;
iWidth;
//注意,Windows中三基色的排列顺序是BGR而不是RGB!
B[i,j]=Convert.ToInt32(PixelValues[iPoint++]);
G[i,j]=Convert.ToInt32(PixelValues[iPoint++]);
R[i,j]=Convert.ToInt32(PixelValues[iPoint++]);
returntrue;
R=null;
G=null;
B=null;
returnfalse;
publicstaticBitmapFromRGB(int[,]R,int[,]G,int[,]B)
intiWidth=G.GetLength
(1);
intiHeight=G.GetLength(0);
BitmapResult=newBitmap(iWidth,iHeight,System.Drawing.Imaging.PixelFormat.Format24bppRgb);
System.Drawing.Imaging.BitmapDatabmpData=Result.LockBits(rect,System.Drawing.Imaging.ImageLockMode.ReadWrite,System.Drawing.Imaging.PixelFormat.Format24bppRgb);
intiStride=bmpData.Stride;
intiBytes=iWidth*iHeight*3;
intiG=G[i,j];
intiB=B[i,j];
intiR=R[i,j];
PixelValues[iPoint]=Convert.ToByte(iB);
PixelValues[iPoint+1]=Convert.ToByte(iG);
PixelValues[iPoint+2]=Convert.ToByte(iR);
iPoint+=3;
System.Runtime.InteropServices.Marshal.Copy(PixelValues,0,iPtr,iBytes);
Result.UnlockBits(bmpData);
returnResult;
publicstaticboolGetGray(BitmapsrcBitmap,outbyte[,]gray)
BitmaptempBitmap;
if(srcBitmap.PixelFormat!
=PixelFormat.Format8bppIndexed)
tempBitmap=ImageProcess.Image.Gray(srcBitmap);
else
tempBitmap=srcBitmap;
intwide=tempBitmap.Width;
intheight=tempBitmap.Height;
gray=newbyte[height,wide];
BitmapDatagbmData=tempBitmap.LockBits(newRectangle(0,0,wide,height),
System.IntPtrScanG=gbmData.Scan0;
intgOffset=gbmData.Stride-wide;
unsafe
byte*g=(byte*)(void*)ScanG;
//foreachpixel
x++,g++)
gray[y,x]=*g;
g+=gOffset;
tempBitmap.UnlockBits(gbmData);
returntrue;
publicstaticBitmapFromGray(byte[,]Gray)
intiWidth=Gray.GetLength
(1);
intiHeight=Gray.GetLength(0);
BitmapdstBitmap=ImageProcess.Image.CreateGrayscaleImage(iWidth,iHeight);
BitmapDatagbmData=dstBitmap.LockBits(newRectangle(0,0,iWidth,iH