C#验证码识别类完整实例
本文实例讲述了C#验证码识别类。分享给大家供大家参考。具体实现方法如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Drawing;
usingSystem.Drawing.Imaging;
usingSystem.Runtime.InteropServices;
namespace验证码处理
{
classVerifyCode
{
publicBitmapbmpobj;
publicVerifyCode(Bitmappic)
{
bmpobj=newBitmap(pic);//转换为Format32bppRgb
}
///<summary>
///根据RGB,计算灰度值
///</summary>
///<paramname="posClr">Color值</param>
///<returns>灰度值,整型</returns>
privateintGetGrayNumColor(System.Drawing.ColorposClr)
{
return(posClr.R*19595+posClr.G*38469+posClr.B*7472)>>16;
}
///<summary>
///灰度转换,逐点方式
///</summary>
publicvoidGrayByPixels()
{
for(inti=0;i<bmpobj.Height;i++)
{
for(intj=0;j<bmpobj.Width;j++)
{
inttmpValue=GetGrayNumColor(bmpobj.GetPixel(j,i));
bmpobj.SetPixel(j,i,Color.FromArgb(tmpValue,tmpValue,tmpValue));
}
}
}
///<summary>
///去图形边框
///</summary>
///<paramname="borderWidth"></param>
publicvoidClearPicBorder(intborderWidth)
{
for(inti=0;i<bmpobj.Height;i++)
{
for(intj=0;j<bmpobj.Width;j++)
{
if(i<borderWidth||j<borderWidth||j>bmpobj.Width-1-borderWidth||i>bmpobj.Height-1-borderWidth)
bmpobj.SetPixel(j,i,Color.FromArgb(255,255,255));
}
}
}
///<summary>
///灰度转换,逐行方式
///</summary>
publicvoidGrayByLine()
{
Rectanglerec=newRectangle(0,0,bmpobj.Width,bmpobj.Height);
BitmapDatabmpData=bmpobj.LockBits(rec,ImageLockMode.ReadWrite,bmpobj.PixelFormat);//PixelFormat.Format32bppPArgb);
//bmpData.PixelFormat=PixelFormat.Format24bppRgb;
IntPtrscan0=bmpData.Scan0;
intlen=bmpobj.Width*bmpobj.Height;
int[]pixels=newint[len];
Marshal.Copy(scan0,pixels,0,len);
//对图片进行处理
intGrayValue=0;
for(inti=0;i<len;i++)
{
GrayValue=GetGrayNumColor(Color.FromArgb(pixels[i]));
pixels[i]=(byte)(Color.FromArgb(GrayValue,GrayValue,GrayValue)).ToArgb();//Color转byte
}
bmpobj.UnlockBits(bmpData);
////输出
//GCHandlegch=GCHandle.Alloc(pixels,GCHandleType.Pinned);
//bmpOutput=newBitmap(bmpobj.Width,bmpobj.Height,bmpData.Stride,bmpData.PixelFormat,gch.AddrOfPinnedObject());
//gch.Free();
}
///<summary>
///得到有效图形并调整为可平均分割的大小
///</summary>
///<paramname="dgGrayValue">灰度背景分界值</param>
///<paramname="CharsCount">有效字符数</param>
///<returns></returns>
publicvoidGetPicValidByValue(intdgGrayValue,intCharsCount)
{
intposx1=bmpobj.Width;intposy1=bmpobj.Height;
intposx2=0;intposy2=0;
for(inti=0;i<bmpobj.Height;i++)//找有效区
{
for(intj=0;j<bmpobj.Width;j++)
{
intpixelValue=bmpobj.GetPixel(j,i).R;
if(pixelValue<dgGrayValue)//根据灰度值
{
if(posx1>j)posx1=j;
if(posy1>i)posy1=i;
if(posx2<j)posx2=j;
if(posy2<i)posy2=i;
};
};
};
//确保能整除
intSpan=CharsCount-(posx2-posx1+1)%CharsCount;//可整除的差额数
if(Span<CharsCount)
{
intleftSpan=Span/2;//分配到左边的空列,如span为单数,则右边比左边大1
if(posx1>leftSpan)
posx1=posx1-leftSpan;
if(posx2+Span-leftSpan<bmpobj.Width)
posx2=posx2+Span-leftSpan;
}
//复制新图
RectanglecloneRect=newRectangle(posx1,posy1,posx2-posx1+1,posy2-posy1+1);
bmpobj=bmpobj.Clone(cloneRect,bmpobj.PixelFormat);
}
///<summary>
///得到有效图形,图形为类变量
///</summary>
///<paramname="dgGrayValue">灰度背景分界值</param>
///<paramname="CharsCount">有效字符数</param>
///<returns></returns>
publicvoidGetPicValidByValue(intdgGrayValue)
{
intposx1=bmpobj.Width;intposy1=bmpobj.Height;
intposx2=0;intposy2=0;
for(inti=0;i<bmpobj.Height;i++)//找有效区
{
for(intj=0;j<bmpobj.Width;j++)
{
intpixelValue=bmpobj.GetPixel(j,i).R;
if(pixelValue<dgGrayValue)//根据灰度值
{
if(posx1>j)posx1=j;
if(posy1>i)posy1=i;
if(posx2<j)posx2=j;
if(posy2<i)posy2=i;
};
};
};
//复制新图
RectanglecloneRect=newRectangle(posx1,posy1,posx2-posx1+1,posy2-posy1+1);
bmpobj=bmpobj.Clone(cloneRect,bmpobj.PixelFormat);
}
///<summary>
///得到有效图形,图形由外面传入
///</summary>
///<paramname="dgGrayValue">灰度背景分界值</param>
///<paramname="CharsCount">有效字符数</param>
///<returns></returns>
publicBitmapGetPicValidByValue(Bitmapsinglepic,intdgGrayValue)
{
intposx1=singlepic.Width;intposy1=singlepic.Height;
intposx2=0;intposy2=0;
for(inti=0;i<singlepic.Height;i++)//找有效区
{
for(intj=0;j<singlepic.Width;j++)
{
intpixelValue=singlepic.GetPixel(j,i).R;
if(pixelValue<dgGrayValue)//根据灰度值
{
if(posx1>j)posx1=j;
if(posy1>i)posy1=i;
if(posx2<j)posx2=j;
if(posy2<i)posy2=i;
};
};
};
//复制新图
RectanglecloneRect=newRectangle(posx1,posy1,posx2-posx1+1,posy2-posy1+1);
returnsinglepic.Clone(cloneRect,singlepic.PixelFormat);
}
///<summary>
///平均分割图片
///</summary>
///<paramname="RowNum">水平上分割数</param>
///<paramname="ColNum">垂直上分割数</param>
///<returns>分割好的图片数组</returns>
publicBitmap[]GetSplitPics(intRowNum,intColNum)
{
if(RowNum==0||ColNum==0)
returnnull;
intsingW=bmpobj.Width/RowNum;
intsingH=bmpobj.Height/ColNum;
Bitmap[]PicArray=newBitmap[RowNum*ColNum];
RectanglecloneRect;
for(inti=0;i<ColNum;i++)//找有效区
{
for(intj=0;j<RowNum;j++)
{
cloneRect=newRectangle(j*singW,i*singH,singW,singH);
PicArray[i*RowNum+j]=bmpobj.Clone(cloneRect,bmpobj.PixelFormat);//复制小块图
}
}
returnPicArray;
}
///<summary>
///返回灰度图片的点阵描述字串,1表示灰点,0表示背景
///</summary>
///<paramname="singlepic">灰度图</param>
///<paramname="dgGrayValue">背前景灰色界限</param>
///<returns></returns>
publicstringGetSingleBmpCode(Bitmapsinglepic,intdgGrayValue)
{
Colorpiexl;
stringcode="";
for(intposy=0;posy<singlepic.Height;posy++)
for(intposx=0;posx<singlepic.Width;posx++)
{
piexl=singlepic.GetPixel(posx,posy);
if(piexl.R<dgGrayValue)//Color.Black)
code=code+"1";
else
code=code+"0";
}
returncode;
}
///<summary>
///得到灰度图像前景背景的临界值最大类间方差法
///</summary>
///<returns>前景背景的临界值</returns>
publicintGetDgGrayValue()
{
int[]pixelNum=newint[256];//图象直方图,共256个点
intn,n1,n2;
inttotal;//total为总和,累计值
doublem1,m2,sum,csum,fmax,sb;//sb为类间方差,fmax存储最大方差值
intk,t,q;
intthreshValue=1;//阈值
//生成直方图
for(inti=0;i<bmpobj.Width;i++)
{
for(intj=0;j<bmpobj.Height;j++)
{
//返回各个点的颜色,以RGB表示
pixelNum[bmpobj.GetPixel(i,j).R]++;//相应的直方图加1
}
}
//直方图平滑化
for(k=0;k<=255;k++)
{
total=0;
for(t=-2;t<=2;t++)//与附近2个灰度做平滑化,t值应取较小的值
{
q=k+t;
if(q<0)//越界处理
q=0;
if(q>255)
q=255;
total=total+pixelNum[q];//total为总和,累计值
}
pixelNum[k]=(int)((float)total/5.0+0.5);//平滑化,左边2个+中间1个+右边2个灰度,共5个,所以总和除以5,后面加0.5是用修正值
}
//求阈值
sum=csum=0.0;
n=0;
//计算总的图象的点数和质量矩,为后面的计算做准备
for(k=0;k<=255;k++)
{
sum+=(double)k*(double)pixelNum[k];//x*f(x)质量矩,也就是每个灰度的值乘以其点数(归一化后为概率),sum为其总和
n+=pixelNum[k];//n为图象总的点数,归一化后就是累积概率
}
fmax=-1.0;//类间方差sb不可能为负,所以fmax初始值为-1不影响计算的进行
n1=0;
for(k=0;k<256;k++)//对每个灰度(从0到255)计算一次分割后的类间方差sb
{
n1+=pixelNum[k];//n1为在当前阈值遍前景图象的点数
if(n1==0){continue;}//没有分出前景后景
n2=n-n1;//n2为背景图象的点数
if(n2==0){break;}//n2为0表示全部都是后景图象,与n1=0情况类似,之后的遍历不可能使前景点数增加,所以此时可以退出循环
csum+=(double)k*pixelNum[k];//前景的“灰度的值*其点数”的总和
m1=csum/n1;//m1为前景的平均灰度
m2=(sum-csum)/n2;//m2为背景的平均灰度
sb=(double)n1*(double)n2*(m1-m2)*(m1-m2);//sb为类间方差
if(sb>fmax)//如果算出的类间方差大于前一次算出的类间方差
{
fmax=sb;//fmax始终为最大类间方差(otsu)
threshValue=k;//取最大类间方差时对应的灰度的k就是最佳阈值
}
}
returnthreshValue;
}
///<summary>
///去掉杂点(适合杂点/杂线粗为1)
///</summary>
///<paramname="dgGrayValue">背前景灰色界限</param>
///<returns></returns>
publicvoidClearNoise(intdgGrayValue,intMaxNearPoints)
{
Colorpiexl;
intnearDots=0;
//逐点判断
for(inti=0;i<bmpobj.Width;i++)
for(intj=0;j<bmpobj.Height;j++)
{
piexl=bmpobj.GetPixel(i,j);
if(piexl.R<dgGrayValue)
{
nearDots=0;
//判断周围8个点是否全为空
if(i==0||i==bmpobj.Width-1||j==0||j==bmpobj.Height-1)//边框全去掉
{
bmpobj.SetPixel(i,j,Color.FromArgb(255,255,255));
}
else
{
if(bmpobj.GetPixel(i-1,j-1).R<dgGrayValue)nearDots++;
if(bmpobj.GetPixel(i,j-1).R<dgGrayValue)nearDots++;
if(bmpobj.GetPixel(i+1,j-1).R<dgGrayValue)nearDots++;
if(bmpobj.GetPixel(i-1,j).R<dgGrayValue)nearDots++;
if(bmpobj.GetPixel(i+1,j).R<dgGrayValue)nearDots++;
if(bmpobj.GetPixel(i-1,j+1).R<dgGrayValue)nearDots++;
if(bmpobj.GetPixel(i,j+1).R<dgGrayValue)nearDots++;
if(bmpobj.GetPixel(i+1,j+1).R<dgGrayValue)nearDots++;
}
if(nearDots<MaxNearPoints)
bmpobj.SetPixel(i,j,Color.FromArgb(255,255,255));//去掉单点&&粗细小3邻边点
}
else//背景
bmpobj.SetPixel(i,j,Color.FromArgb(255,255,255));
}
}
///<summary>
///3×3中值滤波除杂
///</summary>
///<paramname="dgGrayValue"></param>
publicvoidClearNoise(intdgGrayValue)
{
intx,y;
byte[]p=newbyte[9];//最小处理窗口3*3
bytes;
//byte[]lpTemp=newBYTE[nByteWidth*nHeight];
inti,j;
//--!!!!!!!!!!!!!!下面开始窗口为3×3中值滤波!!!!!!!!!!!!!!!!
for(y=1;y<bmpobj.Height-1;y++)//--第一行和最后一行无法取窗口
{
for(x=1;x<bmpobj.Width-1;x++)
{
//取9个点的值
p[0]=bmpobj.GetPixel(x-1,y-1).R;
p[1]=bmpobj.GetPixel(x,y-1).R;
p[2]=bmpobj.GetPixel(x+1,y-1).R;
p[3]=bmpobj.GetPixel(x-1,y).R;
p[4]=bmpobj.GetPixel(x,y).R;
p[5]=bmpobj.GetPixel(x+1,y).R;
p[6]=bmpobj.GetPixel(x-1,y+1).R;
p[7]=bmpobj.GetPixel(x,y+1).R;
p[8]=bmpobj.GetPixel(x+1,y+1).R;
//计算中值
for(j=0;j<5;j++)
{
for(i=j+1;i<9;i++)
{
if(p[j]>p[i])
{
s=p[j];
p[j]=p[i];
p[i]=s;
}
}
}
//if(bmpobj.GetPixel(x,y).R<dgGrayValue)
bmpobj.SetPixel(x,y,Color.FromArgb(p[4],p[4],p[4]));//给有效值付中值
}
}
}
///<summary>
///该函数用于对图像进行腐蚀运算。结构元素为水平方向或垂直方向的三个点,
///中间点位于原点;或者由用户自己定义3×3的结构元素。
///</summary>
///<paramname="dgGrayValue">前后景临界值</param>
///<paramname="nMode">腐蚀方式:0表示水平方向,1垂直方向,2自定义结构元素。</param>
///<paramname="structure">自定义的3×3结构元素</param>
publicvoidErosionPic(intdgGrayValue,intnMode,bool[,]structure)
{
intlWidth=bmpobj.Width;
intlHeight=bmpobj.Height;
BitmapnewBmp=newBitmap(lWidth,lHeight);
inti,j,n,m;//循环变量
if(nMode==0)
{
//使用水平方向的结构元素进行腐蚀
//由于使用1×3的结构元素,为防止越界,所以不处理最左边和最右边
//的两列像素
for(j=0;j<lHeight;j++)
{
for(i=1;i<lWidth-1;i++)
{
//目标图像中的当前点先赋成黑色
newBmp.SetPixel(i,j,Color.Black);
//如果源图像中当前点自身或者左右有一个点不是黑色,
//则将目标图像中的当前点赋成白色
if(bmpobj.GetPixel(i-1,j).R>dgGrayValue||
bmpobj.GetPixel(i,j).R>dgGrayValue||
bmpobj.GetPixel(i+1,j).R>dgGrayValue)
newBmp.SetPixel(i,j,Color.White);
}
}
}
elseif(nMode==1)
{
//使用垂真方向的结构元素进行腐蚀
//由于使用3×1的结构元素,为防止越界,所以不处理最上边和最下边
//的两行像素
for(j=1;j<lHeight-1;j++)
{
for(i=0;i<lWidth;i++)
{
//目标图像中的当前点先赋成黑色
newBmp.SetPixel(i,j,Color.Black);
//如果源图像中当前点自身或者左右有一个点不是黑色,
//则将目标图像中的当前点赋成白色
if(bmpobj.GetPixel(i,j-1).R>dgGrayValue||
bmpobj.GetPixel(i,j).R>dgGrayValue||
bmpobj.GetPixel(i,j+1).R>dgGrayValue)
newBmp.SetPixel(i,j,Color.White);
}
}
}
else
{
if(structure.Length!=9)//检查自定义结构
return;
//使用自定义的结构元素进行腐蚀
//由于使用3×3的结构元素,为防止越界,所以不处理最左边和最右边
//的两列像素和最上边和最下边的两列像素
for(j=1;j<lHeight-1;j++)
{
for(i=1;i<lWidth-1;i++)
{
//目标图像中的当前点先赋成黑色
newBmp.SetPixel(i,j,Color.Black);
//如果原图像中对应结构元素中为黑色的那些点中有一个不是黑色,
//则将目标图像中的当前点赋成白色
for(m=0;m<3;m++)
{
for(n=0;n<3;n++)
{
if(!structure[m,n])
continue;
if(bmpobj.GetPixel(i+m-1,j+n-1).R>dgGrayValue)
{
newBmp.SetPixel(i,j,Color.White);
break;
}
}
}
}
}
}
bmpobj=newBmp;
}
///<summary>
///该函数用于对图像进行细化运算。要求目标图像为灰度图像
///</summary>
///<paramname="dgGrayValue"></param>
publicvoidThiningPic(intdgGrayValue)
{
intlWidth=bmpobj.Width;
intlHeight=bmpobj.Height;
//BitmapnewBmp=newBitmap(lWidth,lHeight);
boolbModified;//脏标记
inti,j,n,m;//循环变量
//四个条件
boolbCondition1;
boolbCondition2;
boolbCondition3;
boolbCondition4;
intnCount;//计数器
int[,]neighbour=newint[5,5];//5×5相邻区域像素值
bModified=true;
while(bModified)
{
bModified=false;
//由于使用5×5的结构元素,为防止越界,所以不处理外围的几行和几列像素
for(j=2;j<lHeight-2;j++)
{
for(i=2;i<lWidth-2;i++)
{
bCondition1=false;
bCondition2=false;
bCondition3=false;
bCondition4=false;
if(bmpobj.GetPixel(i,j).R>dgGrayValue)
{
if(bmpobj.GetPixel(i,j).R<255)
bmpobj.SetPixel(i,j,Color.White);
continue;
}
//获得当前点相邻的5×5区域内像素值,白色用0代表,黑色用1代表
for(m=0;m<5;m++)
{
for(n=0;n<5;n++)
{
neighbour[m,n]=bmpobj.GetPixel(i+m-2,j+n-2).R<dgGrayValue?1:0;
}
}
//逐个判断条件。
//判断2<=NZ(P1)<=6
nCount=neighbour[1,1]+neighbour[1,2]+neighbour[1,3]
+neighbour[2,1]+neighbour[2,3]+
+neighbour[3,1]+neighbour[3,2]+neighbour[3,3];
if(nCount>=2&&nCount<=6)
{
bCondition1=true;
}
//判断Z0(P1)=1
nCount=0;
if(neighbour[1,2]==0&&neighbour[1,1]==1)
nCount++;
if(neighbour[1,1]==0&&neighbour[2,1]==1)
nCount++;
if(neighbour[2,1]==0&&neighbour[3,1]==1)
nCount++;
if(neighbour[3,1]==0&&neighbour[3,2]==1)
nCount++;
if(neighbour[3,2]==0&&neighbour[3,3]==1)
nCount++;
if(neighbour[3,3]==0&&neighbour[2,3]==1)
nCount++;
if(neighbour[2,3]==0&&neighbour[1,3]==1)
nCount++;
if(neighbour[1,3]==0&&neighbour[1,2]==1)
nCount++;
if(nCount==1)
bCondition2=true;
//判断P2*P4*P8=0orZ0(p2)!=1
if(neighbour[1,2]*neighbour[2,1]*neighbour[2,3]==0)
{
bCondition3=true;
}
else
{
nCount=0;
if(neighbour[0,2]==0&&neighbour[0,1]==1)
nCount++;
if(neighbour[0,1]==0&&neighbour[1,1]==1)
nCount++;
if(neighbour[1,1]==0&&neighbour[2,1]==1)
nCount++;
if(neighbour[2,1]==0&&neighbour[2,2]==1)
nCount++;
if(neighbour[2,2]==0&&neighbour[2,3]==1)
nCount++;
if(neighbour[2,3]==0&&neighbour[1,3]==1)
nCount++;
if(neighbour[1,3]==0&&neighbour[0,3]==1)
nCount++;
if(neighbour[0,3]==0&&neighbour[0,2]==1)
nCount++;
if(nCount!=1)
bCondition3=true;
}
//判断P2*P4*P6=0orZ0(p4)!=1
if(neighbour[1,2]*neighbour[2,1]*neighbour[3,2]==0)
{
bCondition4=true;
}
else
{
nCount=0;
if(neighbour[1,1]==0&&neighbour[1,0]==1)
nCount++;
if(neighbour[1,0]==0&&neighbour[2,0]==1)
nCount++;
if(neighbour[2,0]==0&&neighbour[3,0]==1)
nCount++;
if(neighbour[3,0]==0&&neighbour[3,1]==1)
nCount++;
if(neighbour[3,1]==0&&neighbour[3,2]==1)
nCount++;
if(neighbour[3,2]==0&&neighbour[2,2]==1)
nCount++;
if(neighbour[2,2]==0&&neighbour[1,2]==1)
nCount++;
if(neighbour[1,2]==0&&neighbour[1,1]==1)
nCount++;
if(nCount!=1)
bCondition4=true;
}
if(bCondition1&&bCondition2&&bCondition3&&bCondition4)
{
bmpobj.SetPixel(i,j,Color.White);
bModified=true;
}
else
{
bmpobj.SetPixel(i,j,Color.Black);
}
}
}
}
//复制细化后的图像
//bmpobj=newBmp;
}
///<summary>
///锐化要启用不安全代码编译
///</summary>
///<paramname="val">锐化程度。取值[0,1]。值越大锐化程度越高</param>
///<returns>锐化后的图像</returns>
publicvoidSharpen(floatval)
{
intw=bmpobj.Width;
inth=bmpobj.Height;
BitmapbmpRtn=newBitmap(w,h,PixelFormat.Format24bppRgb);
BitmapDatasrcData=bmpobj.LockBits(newRectangle(0,0,w,h),ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb);
BitmapDatadstData=bmpRtn.LockBits(newRectangle(0,0,w,h),ImageLockMode.WriteOnly,PixelFormat.Format24bppRgb);
unsafe
{
byte*pIn=(byte*)srcData.Scan0.ToPointer();
byte*pOut=(byte*)dstData.Scan0.ToPointer();
intstride=srcData.Stride;
byte*p;
for(inty=0;y<h;y++)
{
for(intx=0;x<w;x++)
{
//取周围9点的值。位于边缘上的点不做改变。
if(x==0||x==w-1||y==0||y==h-1)
{
//不做
pOut[0]=pIn[0];
pOut[1]=pIn[1];
pOut[2]=pIn[2];
}
else
{
intr1,r2,r3,r4,r5,r6,r7,r8,r0;
intg1,g2,g3,g4,g5,g6,g7,g8,g0;
intb1,b2,b3,b4,b5,b6,b7,b8,b0;
floatvR,vG,vB;
//左上
p=pIn-stride-3;
r1=p[2];
g1=p[1];
b1=p[0];
//正上
p=pIn-stride;
r2=p[2];
g2=p[1];
b2=p[0];
//右上
p=pIn-stride+3;
r3=p[2];
g3=p[1];
b3=p[0];
//左侧
p=pIn-3;
r4=p[2];
g4=p[1];
b4=p[0];
//右侧
p=pIn+3;
r5=p[2];
g5=p[1];
b5=p[0];
//右下
p=pIn+stride-3;
r6=p[2];
g6=p[1];
b6=p[0];
//正下
p=pIn+stride;
r7=p[2];
g7=p[1];
b7=p[0];
//右下
p=pIn+stride+3;
r8=p[2];
g8=p[1];
b8=p[0];
//自己
p=pIn;
r0=p[2];
g0=p[1];
b0=p[0];
vR=(float)r0-(float)(r1+r2+r3+r4+r5+r6+r7+r8)/8;
vG=(float)g0-(float)(g1+g2+g3+g4+g5+g6+g7+g8)/8;
vB=(float)b0-(float)(b1+b2+b3+b4+b5+b6+b7+b8)/8;
vR=r0+vR*val;
vG=g0+vG*val;
vB=b0+vB*val;
if(vR>0)
{
vR=Math.Min(255,vR);
}
else
{
vR=Math.Max(0,vR);
}
if(vG>0)
{
vG=Math.Min(255,vG);
}
else
{
vG=Math.Max(0,vG);
}
if(vB>0)
{
vB=Math.Min(255,vB);
}
else
{
vB=Math.Max(0,vB);
}
pOut[0]=(byte)vB;
pOut[1]=(byte)vG;
pOut[2]=(byte)vR;
}
pIn+=3;
pOut+=3;
}//endofx
pIn+=srcData.Stride-w*3;
pOut+=srcData.Stride-w*3;
}//endofy
}
bmpobj.UnlockBits(srcData);
bmpRtn.UnlockBits(dstData);
bmpobj=bmpRtn;
}
///<summary>
///图片二值化
///</summary>
///<paramname="hsb"></param>
publicvoidBitmapTo1Bpp(Doublehsb)
{
intw=bmpobj.Width;
inth=bmpobj.Height;
Bitmapbmp=newBitmap(w,h,PixelFormat.Format1bppIndexed);
BitmapDatadata=bmp.LockBits(newRectangle(0,0,w,h),ImageLockMode.ReadWrite,PixelFormat.Format1bppIndexed);
for(inty=0;y<h;y++)
{
byte[]scan=newbyte[(w+7)/8];
for(intx=0;x<w;x++)
{
Colorc=bmpobj.GetPixel(x,y);
if(c.GetBrightness()>=hsb)scan[x/8]|=(byte)(0x80>>(x%8));
}
Marshal.Copy(scan,0,(IntPtr)((int)data.Scan0+data.Stride*y),scan.Length);
}
bmp.UnlockBits(data);
bmpobj=bmp;
}
}
}
希望本文所述对大家的C#程序设计有所帮助。