验证码识别思路及C#代码
/// <summary>
/// 得到验证码图片
/// </summary>
/// <returns></returns>
private Bitmap Get_Bmp()
{
IHTMLDocument2 doc = (webBrowser1.Document.DomDocument as IHTMLDocument2);
int iImgCount = doc.images.length;
for (int iss = 0; iss < iImgCount; iss++)
{
IHTMLImgElement img = (IHTMLImgElement)doc.images.item(iss, 0);
if (img != null && img.src.IndexOf("createVerifyImageServlet") > 0)
{
IHTMLControlElement ce = (IHTMLControlElement)img;
IHTMLControlRange cp = (IHTMLControlRange)((IHTMLElement2)doc.body).createControlRange();
cp.add(ce);
cp.execCommand("Copy", false, null);
return (Bitmap)Clipboard.GetImage();
Clipboard.Clear();
break;
}
}
return (Bitmap)Clipboard.GetImage();
}
第二种方法是直接利用流方式读取,然后把图片放到内存当中。
//其他辅助函数#region 其他辅助函数
/**/
/// <summary>
/// 加载验证码
/// </summary>
/// <returns>验证码图形</returns>
public Bitmap crImg(string ImgUrl)
{
Bitmap bmp = null;
//响应
HttpWebResponse response = null;
try
{
//请求
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.ImgUrl);
//得到响应
response = (HttpWebResponse)request.GetResponse();
//从响应流直接创建图片
bmp = new Bitmap(response.GetResponseStream());
}
catch
{
}
finally
{//清理资源
if (response != null)
{
response.Close();
}
}
return bmp;
}
第二步,得到验证图片后,一般我们都要进行灰度处理,方便识别。
/// <summary>
/// 灰度处理
/// </summary>
/// <param name="bmp">要处理的图片</param>
/// <returns>返回处理后的图片</returns>
public Bitmap GrayByPixels(Bitmap bmp)
{
try
{
for (int i = 0; i < bmp.Height; i++)
{
for (int j = 0; j < bmp.Width; j++)
{
int tmpValue = GetGrayNumColor(bmp.GetPixel(j, i));
bmp.SetPixel(j, i, Color.FromArgb(tmpValue, tmpValue, tmpValue));
}
}
}
catch (System.Exception e)
{
}
return Bmp;
}
第三步,就是要把图片分割,为什么要分呢,因为分开后来识别第一个数字。这里发出4位数代码。
/// 分割图片为4分
/// </summary>
/// <param name="bmp">要分割的图片</param>
/// <returns>返回分割后的图片数组</returns>
public Bitmap[] F_BPM(Bitmap bmp)
{
Bitmap[] P_BMP=null;
try
{
Rectangle clo = new Rectangle(8, 5, 43, 15);
bmp = bmp.Clone(clo, bmp.PixelFormat);
P_BMP = new Bitmap[10 * 15];
clo.X = 0;
clo.Y = 0;
clo.Width = 10;
P_BMP[0] = bmp.Clone(clo, bmp.PixelFormat);
clo.X = 11;
P_BMP[1] = bmp.Clone(clo, bmp.PixelFormat);
clo.X = 22;
P_BMP[2] = bmp.Clone(clo, bmp.PixelFormat);
clo.X = 33;
P_BMP[3] = bmp.Clone(clo, bmp.PixelFormat);
}
catch (System.Exception e)
{
}
return P_BMP;
}
第四步,得到特征码数组,这里发出的代码为特征码前十位,中间十位,和后十位。
/// <summary>
/// 返回灰度图片的点阵描述字串,1表示灰点,0表示背景
/// </summary>
/// <param name="singlepic">灰度图</param>
/// <param name="dgGrayValue">背前景灰色界限</param>
/// <returns>返回特征码</returns>
public string[] GetSingleBmpCode(Bitmap[] singlepic, int dgGrayValue)
{
Color piexl;
string code = "";
string[] codes = new string[4] ;
try
{
for (int i = 0; i < 4;i++ )
{
code = "";
for (int posy = 0; posy < singlepic[i].Height; posy++)
{
for (int posx = 0; posx < singlepic[i].Width; posx++)
{
piexl = singlepic[i].GetPixel(posx, posy);
if (piexl.R < dgGrayValue) // Color.Black )
{
if (posx > 0 & posy > 0 & posx < 9 & posy < 14)
{
if (singlepic[i].GetPixel(posx, posy - 1).R < dgGrayValue | singlepic[i].GetPixel(posx, posy + 1).R < dgGrayValue | singlepic[i].GetPixel(posx - 1, posy).R < dgGrayValue | singlepic[i].GetPixel(posx + 1, posy).R < dgGrayValue)
{
code = code + "1";
}
else
{ code = code + "0"; }
}
else
{ code = code + "1"; }
}
else
{ code = code + "0"; }
}
}
codes[i] = codes[i] + code;
}
}
catch (System.Exception e)
{
}
return codes;
}