[转]用于验证码图片识别的类(C#源码)

本文转自:http://www.cnblogs.com/yuanbao/archive/2007/09/25/905322.html

最近写了几个网站的验证码图片自动识别程序,尽管每个网站的验证码图片都不相同,识别的方法有所差别。但写得多了,也总结出不少相同之处。今天抽空封装出一个基础类来,发现可以很好地重复利用,编写不同的验证码识别程序,效率提高了不少。好东东不能独享,现放出来供大家共同研究,请网友们妥善用之。
封装后的类使用很简单,针对不同的验证码,相应继承修改某些方法,即可简单几句代码就可以实现图片识别了:
GrayByPixels(); //灰度处理
GetPicValidByValue(128, 4); //得到有效空间
Bitmap[] pics = GetSplitPics(4, 1); //分割
string code = GetSingleBmpCode(pics[i], 128); //得到代码串

具体使用,请参见我做的例子:
投票程序示例.exe投票程序源码
(例子说明:使用进程投票,可自动清除Alert弹出窗口,可自动换IP,ADSL用户自行修改Restart.bat中第三行内容)

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace BallotAiying2
{
classUnCodebase
{
publicBitmapbmpobj;
publicUnCodebase(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);
}


/**////<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++)//找有效区
<span styl
分享到:
评论

你可能感兴趣的:(验证码)