主要原理就是识别图片的颜色不同从而转换为文字。不过对于不规则的验证码就不太行了。
主要代码如下:
recordString = string.Empty;
IHTMLControlRange imgRange;
IHTMLDocument2 document = new HTMLDocumentClass();
document = (IHTMLDocument2)this.axWebBrowser.Document;
HTMLBody body = (HTMLBody)document.body;
Bitmap bmp = new Bitmap(50, 20);
foreach (IHTMLImgElement imageElement in document.images)
{
if (imageElement.src.IndexOf("suijitupian") > -1)
{
imgRange = (IHTMLControlRange)body.createControlRange();
imgRange.add((IHTMLControlElement)imageElement);
imgRange.execCommand("Copy", false, null);
bmp = (Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap);
bmp.Save(@"now.bmp");
}
}
this.EraseNoiseDotAndGray(bmp);
this.pictureBox1.Image = bmp;
bmp.Save(@"now_no_noise_dot.bmp");
//从左向右一列一列扫描,寻找四个数字的左右边界以切割
int verticalBlackContent = 0;
int width = 0;
int currentNumberIndex = 0;
int[,] horizonAxisArray = new int[4,2];
//左右边界初始化
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 2; j++)
{
horizonAxisArray[i, j] = 0;
}
}
while (currentNumberIndex <= 3 && width < 50)
{
for (int h = 8; h < 18; h++)
{
if (bmp.GetPixel(width, h).ToArgb() == Color.Black.ToArgb())
{
verticalBlackContent++;
}
}
if (horizonAxisArray[currentNumberIndex, 0] == 0 && verticalBlackContent > 0) //左边界
{
horizonAxisArray[currentNumberIndex, 0] = width;
}
else if (horizonAxisArray[currentNumberIndex, 0] != 0 && horizonAxisArray[currentNumberIndex, 1] == 0 && verticalBlackContent == 0) //右边界
{
horizonAxisArray[currentNumberIndex++, 1] = width - 1;
}
width = width + 1;
verticalBlackContent = 0;
}
int[] tNumArr = new int[4]; //识别后的4个数字
//加载10个标准数字
Bitmap[] sNumArr = new Bitmap[10];
for (int i = 0; i < 10; i++)
{
sNumArr[i] = new Bitmap(@"s" + i + ".bmp");
}
//分割出来的4个数字分别与等宽的标准数字相匹配
for (int i = 0; i < 4; i++)
{
int maxMatch = 0;
Bitmap cutNum = bmp.Clone(new Rectangle(horizonAxisArray[i, 0], 8, horizonAxisArray[i, 1] - horizonAxisArray[i, 0] + 1, 10), PixelFormat.Format24bppRgb);
for (int s = 0; s < 10; s++)
{
if (cutNum.Width == sNumArr[s].Width) //等宽则匹配
{
int curMatch = 0;
for (int j = 0; j < cutNum.Width; j++)
{
for (int k = 0; k < 10; k++)
{
if (cutNum.GetPixel(j, k).ToArgb() == sNumArr[s].GetPixel(j, k).ToArgb() &&
cutNum.GetPixel(j, k).ToArgb() == Color.Black.ToArgb() &&
sNumArr[s].GetPixel(j, k).ToArgb() == Color.Black.ToArgb())
{
curMatch++;
}
}
}
if (curMatch > maxMatch)
{
maxMatch = curMatch;
tNumArr[i] = s;
}
}
}
recordString += tNumArr[i] + "";
}
this.richTextBox1.Text = recordString;
private void EraseNoiseDotAndGray(Bitmap bmp)
{
for (int w = 0; w < 50; w++)
{
for (int h = 0; h < 20; h++)
{
if (bmp.GetPixel(w, h).R == 204) //为杂点,变为白色
{
bmp.SetPixel(w, h, Color.White);
}
else if (bmp.GetPixel(w, h).G != 255) //为数字所在点,变为黑色
{
bmp.SetPixel(w, h, Color.Black);
}
}
}
}
这里用了AxWebBrowser控件,结果老是加不到工具栏中去,所以只好手动写了个初始化,然后加到Desinge里。
private AxWebBrowser axWebBrowser = null;
private void InitialAxWebBrowser()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(VCCMainForm));
this.axWebBrowser = new AxSHDocVw.AxWebBrowser();
((System.ComponentModel.ISupportInitialize)(this.axWebBrowser)).BeginInit();
this.axWebBrowser.Dock = System.Windows.Forms.DockStyle.Bottom;
this.axWebBrowser.Enabled = true;
this.axWebBrowser.Location = new System.Drawing.Point(0, 225);
this.axWebBrowser.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axWebBrowser.OcxState")));
this.axWebBrowser.Size = new System.Drawing.Size(592, 212);
this.axWebBrowser.TabIndex = 0;
this.axWebBrowser.ProgressChange += new DWebBrowserEvents2_ProgressChangeEventHandler(axWebBrowser_ProgressChange);
this.axWebBrowser.StatusTextChange += new DWebBrowserEvents2_StatusTextChangeEventHandler(axWebBrowser_StatusTextChange);
this.axWebBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(axWebBrowser_DocumentComplete);
this.Controls.Add(this.axWebBrowser);
}
结果如下:
详细工程:http://download.csdn.net/detail/yysyangyangyangshan/4233915