C#图像处理.docx

上传人:b****5 文档编号:5743440 上传时间:2022-12-31 格式:DOCX 页数:14 大小:31.72KB
下载 相关 举报
C#图像处理.docx_第1页
第1页 / 共14页
C#图像处理.docx_第2页
第2页 / 共14页
C#图像处理.docx_第3页
第3页 / 共14页
C#图像处理.docx_第4页
第4页 / 共14页
C#图像处理.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

C#图像处理.docx

《C#图像处理.docx》由会员分享,可在线阅读,更多相关《C#图像处理.docx(14页珍藏版)》请在冰豆网上搜索。

C#图像处理.docx

C#图像处理

一.Bitmap类

Bitmap对象封装了GDI+中的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义的图像的对象.该类的主要方法和属性如下:

1.GetPixel方法和SetPixel方法:

获取和设置一个图像的指定像素的颜色.

2.PixelFormat属性:

返回图像的像素格式.

3.Palette属性:

获取和设置图像所使用的颜色调色板.

4.HeightWidth属性:

返回图像的高度和宽度.

5.LockBits方法和UnlockBits方法:

分别锁定和解锁系统内存中的位图像素.在基于像素点的图像处理方法中使用LockBits和UnlockBits是一个很好的方式,这两种方法可以使我们指定像素的范围来控制位图的任意一部分,从而消除了通过循环对位图的像素逐个进行处理,每调用LockBits之后都应该调用一次UnlockBits.

二.BitmapData类

BitmapData对象指定了位图的属性

1.Height属性:

被锁定位图的高度.

2.Width属性:

被锁定位图的高度.

3.PixelFormat属性:

数据的实际像素格式.

4.Scan0属性:

被锁定数组的首字节地址,如果整个图像被锁定,则是图像的第一个字节地址.

5.Stride属性:

步幅,也称为扫描宽度.

如上图所示,数组的长度并不一定等于图像像素数组的长度,还有一部分未用区域,这涉及到位图的数据结构,系统要保证每行的字节数必须为4的倍数.

三.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=@"Bitmap文件(*.bmp)|*.bmp|Jpeg文件(*.jpg)|*.jpg|所有合适文件(*.bmp,*.jpg)|*.bmp;*.jpg";

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;

case".bmp":

format=ImageFormat.Bmp;

break;

default:

MessageBox.Show(this,"Unsupportedimageformatwasspecified","Error",

MessageBoxButtons.OK,MessageBoxIcon.Error);

return;

}

try

{

showBitmap.Save(saveFileDialog.FileName,format);

}

catch(Exception)

{

MessageBox.Show(this,"Failedwritingimagefile","Error",

MessageBoxButtons.OK,MessageBoxIcon.Error);

}

}

}

}

//窗口重绘,在窗体上显示图像,重载Paint

privatevoidfrmMain_Paint(objectsender,System.Windows.Forms.PaintEventArgse)

{

if(showBitmap!

=null)

{

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为例

this.Invalidate();

}

二.提取像素法

这种方法简单易懂,但相当耗时,完全不可取.

publicstaticBitmapRGB2Gray(BitmapsrcBitmap)

{

ColorsrcColor;

intwide=srcBitmap.Width;

intheight=srcBitmap.Height;

for(inty=0;y

for(intx=0;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;

}//#

三.内存法

这是比较常用的方法

publicstaticBitmapRGB2Gray(BitmapsrcBitmap)

{

intwide=srcBitmap.Width;

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

for(intj=0;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#的特点

publicstaticBitmapRGB2Gray(BitmapsrcBitmap)

{

intwide=srcBitmap.Width;

intheight=srcBitmap.Height;

Rectanglerect=newRectangle(0,0,wide,height);

BitmapDatasrcBmData=srcBitmap.LockBits(rect,

ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);

BitmapdstBitmap=CreateGrayscaleImage(wide,height);

BitmapDatadstBmData=dstBitmap.LockBits(rect,

ImageLockMode.ReadWrite,PixelFormat.Format8bppIndexed);

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;

for(inty=0;y

{

for(intx=0;x

{

blue=srcP[0];

green=srcP[1];

red=srcP[2];

*dstP=(byte)(.299*red+.587*green+.114*blue);

}

srcP+=srcOffset;

dstP+=dstOffset;

}

}

srcBitmap.UnlockBits(srcBmData);

dstBitmap.UnlockBits(dstBmData);

returndstBitmap;

}//#

五.矩阵法

并不是什么新方法,只是将图像数据分做R,G,B三个矩阵(二维数组)存储,类似MATLAB的习惯.

publicstaticboolGetRGB(BitmapSource,outint[,]R,outint[,]G,outint[,]B)

{

try

{

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;

for(inti=0;i

{

for(intj=0;j

{

//注意,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;

}

catch(Exception)

{

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);

Rectanglerect=newRectangle(0,0,iWidth,iHeight);

System.Drawing.Imaging.BitmapDatabmpData=Result.LockBits(rect,System.Drawing.Imaging.ImageLockMode.ReadWrite,System.Drawing.Imaging.PixelFormat.Format24bppRgb);

IntPtriPtr=bmpData.Scan0;

intiStride=bmpData.Stride;

intiBytes=iWidth*iHeight*3;

byte[]PixelValues=newbyte[iBytes];

intiPoint=0;

for(inti=0;i

for(intj=0;j

{

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),

ImageLockMode.ReadWrite,PixelFormat.Format8bppIndexed);

System.IntPtrScanG=gbmData.Scan0;

intgOffset=gbmData.Stride-wide;

unsafe

{

byte*g=(byte*)(void*)ScanG;

//foreachpixel

for(inty=0;y

{

//foreachpixel

for(intx=0;x

{

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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1