强大的图片验证码识别代码
今天想刷个投票页面,需要识别验证码,网上搜啊,找到一个图片验证码识别类,改动一下用起来很舒服啊^_^
因为每种类验证码的字符表都不一样,所以需要事先得到此种验证码的字符表
方法呢,就是在调试模式输出一下就看到了
代码如下
UnCodeBase.cs
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
{
class UnCodebase
{
public Bitmap bmpobj;
public UnCodebase(Bitmap pic)
{
// if (pic.PixelFormat == PixelFormat.Format8bppIndexed)
bmpobj = new Bitmap(pic); //转换为Format32bppRgb
}
///
/// 根据RGB,计算灰度值
///
///
Color值
/// 灰度值,整型
private int GetGrayNumColor(System.Drawing.Color posClr)
{
return (posClr.R * 19595 + posClr.G * 38469 + posClr.B * 7472) >> 16;
}
///
/// 灰度转换,逐点方式
///
public void GrayByPixels()
{
for (int i = 0; i < bmpobj.Height; i++)
{
for (int j = 0; j < bmpobj.Width; j++)
{
int tmpValue = GetGrayNumColor(bmpobj.GetPixel(j, i));
bmpobj.SetPixel(j, i, Color.FromArgb(tmpValue, tmpValue, tmpValue));
}
}
}
///
/// 去图形边框
///
///
public void ClearPicBorder(int borderWidth)
{
for (int i = 0; i < bmpobj.Height; i++)
{
for (int j = 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));
}
}
}
///
/// 灰度转换,逐行方式
///
public void GrayByLine()
{
Rectangle rec = new Rectangle(0, 0, bmpobj.Width, bmpobj.Height);
BitmapData bmpData = bmpobj.LockBits(rec, ImageLockMode.ReadWrite, bmpobj.PixelFormat);// PixelFormat.Format32bppPArgb);
// bmpData.PixelFormat = PixelFormat.Format24bppRgb;
IntPtr scan0 = bmpData.Scan0;
int len = bmpobj.Width * bmpobj.Height;
int[] pixels = new int[len];
Marshal.Copy(scan0, pixels, 0, len);
//对图片进行处理
int GrayValue = 0;
for (int i = 0; i < len; i++)
{
GrayValue = GetGrayNumColor(Color.FromArgb(pixels[i]));
pixels[i] = (byte)(Color.FromArgb(GrayValue, GrayValue, GrayValue)).ToArgb(); //Color转byte
}
bmpobj.UnlockBits(bmpData);
////输出
//GCHandle gch = GCHandle.Alloc(pixels, GCHandleType.Pinned);
//bmpOutput = new Bitmap(bmpobj.Width, bmpobj.Height, bmpData.Stride, bmpData.PixelFormat, gch.AddrOfPinnedObject());
//gch.Free();
}
///
/// 得到有效图形并调整为可平均分割的大小
///
///
灰度背景分界值
///
有效字符数
///
public void GetPicValidByValue(int dgGrayValue, int CharsCount)
{
int posx1 = bmpobj.Width; int posy1 = bmpobj.Height;
int posx2 = 0; int posy2 = 0;
for (int i = 0; i < bmpobj.Height; i++) //找有效区
{
for (int j = 0; j < bmpobj.Width; j++)
{
int pixelValue = 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;
};
};
};
// 确保能整除
int Span = CharsCount - (posx2 - posx1 + 1) % CharsCount; //可整除的差额数
if (Span < CharsCount)
{
int leftSpan = Span / 2; //分配到左边的空列 ,如span为单数,则右边比左边大1
if (posx1 > leftSpan)
posx1 = posx1 - leftSpan;
if (posx2 + Span - leftSpan < bmpobj.Width)
posx2 = posx2 + Span - leftSpan;
}
//复制新图
Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1);
bmpobj = bmpobj.Clone(cloneRect, bmpobj.PixelFormat);
}
///
/// 得到有效图形,图形为类变量
///
///
灰度背景分界值
///
有效字符数
///
public void GetPicValidByValue(int dgGrayValue)
{
int posx1 = bmpobj.Width; int posy1 = bmpobj.Height;
int posx2 = 0; int posy2 = 0;
for (int i = 0; i < bmpobj.Height; i++) //找有效区
{
for (int j = 0; j < bmpobj.Width; j++)
{
int pixelValue = 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;
};
};
};
//复制新图
Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1);
bmpobj = bmpobj.Clone(cloneRect, bmpobj.PixelFormat);
}
///
/// 得到有效图形,图形由外面传入
///
///
灰度背景分界值
///
有效字符数
///
public Bitmap GetPicValidByValue(Bitmap singlepic, int dgGrayValue)
{
int posx1 = singlepic.Width; int posy1 = singlepic.Height;
int posx2 = 0; int posy2 = 0;
for (int i = 0; i < singlepic.Height; i++) //找有效区
{
for (int j = 0; j < singlepic.Width; j++)
{
int pixelValue = 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;
};
};
};
//复制新图
Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1);
return singlepic.Clone(cloneRect, singlepic.PixelFormat);
}
///
/// 平均分割图片
///
///
水平上分割数
///
垂直上分割数
/// 分割好的图片数组
public Bitmap [] GetSplitPics(int RowNum,int ColNum)
{
if (RowNum == 0 || ColNum == 0)
return null;
int singW = bmpobj.Width / RowNum;
int singH = bmpobj.Height / ColNum;
Bitmap [] PicArray=new Bitmap[RowNum*ColNum];
Rectangle cloneRect;
for (int i = 0; i < ColNum; i++) //找有效区
{
for (int j = 0; j < RowNum; j++)
{
cloneRect = new Rectangle(j*singW, i*singH, singW , singH);
PicArray[i*RowNum+j]=bmpobj.Clone(cloneRect, bmpobj.PixelFormat);//复制小块图
}
}
return PicArray;
}
///
/// 返回灰度图片的点阵描述字串,1表示灰点,0表示背景
///
///
灰度图
///
背前景灰色界限
///
public string GetSingleBmpCode(Bitmap singlepic, int dgGrayValue)
{
Color piexl;
string code = "";
for (int posy = 0; posy < singlepic.Height; posy++)
for (int posx = 0; posx < singlepic.Width; posx++)
{
piexl = singlepic.GetPixel(posx, posy);
if (piexl.R < dgGrayValue) // Color.Black )
code = code + "1";
else
code = code + "0";
}
return code;
}
}
}
unCodeAiYing.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace BallotAiying2
{
class unCodeAiYing : UnCodebase
{
//字符表
string[,] CodeArray = new string[,] {{"1","00100111000010000100001000010000100001000010011111"},
{"4","000100000100001100010100100100100100111111000100000100001111"},
{"B","1111110010000101000010100010011110001000100100001010000101000011111110"},
{"N","1110111011001001100100101010010101001010100100110010011001001101110010"},
{"0","011110100001100001101101101101101101101101100001100001011110"},
{"M","111011011011011011011011010101010101010101010101010101110101"},
{"F","1111110010000101001000100100011110001001000100100010000001000001110000"},
{"E","1111110010000101001000100100011110001001000100100010000001000011111110"},
{"A","0001000000100000101000010100001010000101000111110010001001000101110111"},
{"G","001111010001100001100000100000100000100011100001010001001110"},
{"K","1110111010001001001000101000011100001010000100100010010001000101110111"},
{"T","1111111100100100010000001000000100000010000001000000100000010000011100"},
{"C","0011111010000110000011000000100000010000001000000100000101000100011100"},
{"4","00010000100011001010100101001011111000100001000111"},
{"9","011100100010100001100001100011011101000001000001100010011100"},
{"S","011111100001100001100000011000000110000001100001100001111110"},
{"Z","111111100010000010000100000100001000001000010000010001111111"},
{"3","011110100001100001000010001100000010000001100001100001011110"},
{"M","1110111011011001101100110110010101001010100101010010101001010101101011"},
{"Q","0011100010001010000011000001100000110000011000001101100101001100011101"},
{"L","1110000010000001000000100000010000001000000100000010000001000011111111"},
{"W","1101011010101001010100101010010101001101100010100001010000101000010100"},
{"D","111110010001010000010000010000010000010000010000010001111110"},
{"I","11111001000010000100001000010000100001000010011111"},
{"U","1110111010001001000100100010010001001000100100010010001001000100011100"},
{"6","00111010001000010000101111100010000100001000001111"},
{"B","111111010000010000010001011110010001010000010000010000111111"},
{"8","011110100001100001100001011110010010100001100001100001011110"},
{"P","1111110010000101000010100001011111001000000100000010000001000001110000"},
{"N","111011011001011001010101010101010101010011010011010011111001"},
{"X","1110111010001000101000010100000100000010000010100001010001000101110111"},
{"X","111011010001001010001010000100000100001010001010010001111011"},
{"D","1111100010001001000010100001010000101000010100001010000101000101111100"},
{"U","111011010001010001010001010001010001010001010001010001001110"},
{"H","1110111010001001000100100010011111001000100100010010001001000101110111"},
{"R","1111100010001001000100100010011110001010000100100010010001000101110011"},
{"V","111011010001010001010001001010001010001010001010000100000100"},
{"O","0011100010001010000011000001100000110000011000001100000101000100011100"},
{"T","111111100100000100000100000100000100000100000100000100001110"},
{"2","011110100001100001000001000010000100001000010000100001111111"},
{"6","001110010001100000100000101110110001100001100001100001011110"},
{"Z","11111100010000100010000100010000100010000100011111"},
{"Y","111011010001010001001010001010000100000100000100000100001110"},
{"Y","1110111010001001000100010100001010000010000001000000100000010000011100"},
{"5","11111100001000010111110000000000000100001000001111"},
{"R","111110010001010001010001011110010100010010010010010001111001"},
{"W","110101010101010101010101010101011011001010001010001010001010"},
{"H","111011010001010001010001011111010001010001010001010001111011"},
{"5","111111100000100000101110110001000001000001100001100001011110"},
{"V","1110111010001001000100100010001010000101000010100001010000010000001000"},
{"J","001111000010000010000010000010000010000010000010100010111100"},
{"7","111111100010100010000100000100001000001000001000001000001000"},
{"O","001110010001100000100000100000100000100000100000010001001110"},
{"F","111111010000010010010010011110010010010010010000010000111000"},
{"C","001111010000100000100000100000100000100000100000010001001110"},
{"Q","001110010001100000100000100000100000100000101100010011001110"},
{"J","0011111000010000001000000100000010000001000000100000010010001001111000"},
{"9","01110100011000010000100010111000000000001000101110"}};
public unCodeAiYing(Bitmap pic)
: base(pic)
{
}
public string getPicnum()
{
GrayByPixels(); //灰度处理
GetPicValidByValue(128, 4); //得到有效空间
Bitmap[] pics = GetSplitPics(4, 1); //分割
if (pics.Length != 4)
{
return ""; //分割错误
}
else // 重新调整大小
{
pics[0] = GetPicValidByValue(pics[0], 128);
pics[1] = GetPicValidByValue(pics[1], 128);
pics[2] = GetPicValidByValue(pics[2], 128);
pics[3] = GetPicValidByValue(pics[3], 128);
}
// if (!textBoxInput.Text.Equals(""))
string result = "";
string dddd = "";
char singleChar = ' ';
{
for (int i = 0; i < 4; i++)
{
string code = GetSingleBmpCode(pics[i], 128); //得到代码串
System.Diagnostics.Debug.WriteLine(code);
for (int arrayIndex = 0; arrayIndex < CodeArray.Length/2; arrayIndex++)
{
if (CodeArray[arrayIndex,1].Equals(code)) //相等
{
dddd = CodeArray[arrayIndex, 0];
//if (arrayIndex < 10) // 0..9
// singleChar = (char)(48 + arrayIndex);
//else if (arrayIndex < 36) //A..Z
// singleChar = (char)(65 + arrayIndex - 10);
//else
// singleChar = (char)(97 + arrayIndex - 36);
//result = result + singleChar;
result = result + dddd;
}
}
}
}
return result;
}
}
}
使用方式
HtmlDocument doc = webBrowser1.Document;
// IHTMLDocument2 doc2 = (IHTMLDocument2)webBrowser1.Document.DomDocument;
// HtmlElement ImgeTag =(HtmlElement) doc2.images.item(0, 0);
HtmlElement ImgeTag = doc.Forms[0].GetElementsByTagName("IMG")[0];
Image numPic = GetWebImage(webBrowser1, ImgeTag); // 得到验证码图片
pictureBox1.Image = numPic;
unCodeAiYing UnCheckobj = new unCodeAiYing((Bitmap)numPic);
string strNum = UnCheckobj.getPicnum(); //识别图片
System.Diagnostics.Debug.WriteLine(strNum);
for (int i = 0; i < doc.All.Count; i++)
{
if (doc.All[i].TagName.ToUpper().Equals("INPUT"))
{
switch (doc.All[i].Name)
{
case "Vcode":
doc.All[i].InnerText = strNum;
break;
case "Submit":
ClickBtn = doc.All[i]; //提交
break;
}
}
}
ClickBtn.InvokeMember("Click"); //执行按扭操作
如果你是第一次来这儿,欢迎订阅
RSS feed。 第一时间看到更多精彩内容,谢谢你的访问!
原文地址:http://ai-2.cn/2010/03/validcodeshibie/
转载请注明出处,非常感谢!
原文地址:http://ai-2.cn/2010/03/validcodeshibie/
转载请注明出处,非常感谢!
Category: c#
You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.



就是System.Diagnostics.Debug.WriteLine(code)吧,就看到字符串了