其实实现一个图片验证码并不是什么难的问题,主要讲究的时验证的实现上如何提高程序的识别难度.所以在实现过程参考了一下google的做法,由于数字或字母适当重叠对人自身识别并不成什么问题,但对于计算增加的难度相对来说就比较高些了.如果感觉难度不大可以调整一下程序让让字母之间紧靠的近一点,也可适当地加下曲线来让分析上更难.不过做得太过的话,估计人自己都搞不清楚了:)
验证码效果


具体实现代码
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
namespace Smark.ImageNumber
{
///
/// Copyright © henryfan 2012
/// Email: henryfan@msn.com
/// HomePage: http://www.ikende.com
/// CreateTime: 2012/10/23 21:18:29
///
public class Generator
{
const string VALUE = "123456789";
private static Dictionary mCharImages = new Dictionary(26);
private static Image mLine;
private static Random mRam = new Random();
public static string GeneratorCode()
{
string code = "";
for (int i = 0; i < 4; i++)
{
code += VALUE.Substring(GetRamValue() % VALUE.Length, 1);
}
return code;
}
static int GetRamValue()
{
return mRam.Next();
}
public static Image GetImage(string code)
{
Bitmap tmpImg = new Bitmap(100, 40);
using (Graphics e = Graphics.FromImage(tmpImg))
{
int offset = 2;
e.FillRectangle(new SolidBrush(Color.White), 0, 0, 200, 60);
List items = new List();
foreach (char key in code)
{
items.Add(GetGeneratorItem(key));
}
for (int i = 0; i < items.Count; i++)
{
if (i > 0)
{
if ((items[i].Value < 0 && items[i - 1].Value > 0) || (items[i].Value > 0 && items[i - 1].Value > 0)
|| (items[i].Value < 0 && items[i - 1].Value < 0))
offset += 12;
else
offset += 18;
}
using (Image img = items[i].DrawImage())
{
if (Math.Abs(items[i].Value) > 20)
e.DrawImage(img, offset, 6);
else if (Math.Abs(items[i].Value) > 20)
e.DrawImage(img, offset, 4);
else
e.DrawImage(img, offset, 2);
}
}
}
return tmpImg;
}
public static System.Collections.IEnumerable GetKeys
{
get
{
return mCharImages.Keys;
}
}
private static GeneratorItem GetGeneratorItem(char key)
{
GeneratorItem item = new GeneratorItem();
int value = GetRamValue() % 25;
if (value < 10)
value = 10;
if (GetRamValue() % 2 == 0)
value = -value;
item.Value = value;
item.Key = key;
return item;
}
class GeneratorItem
{
public int Value { get; set; }
public char Key { get; set; }
public Image DrawImage()
{
Bitmap tmpImg = new Bitmap(50, 50);
using (Graphics e = Graphics.FromImage(tmpImg))
{
e.RotateTransform(Value, System.Drawing.Drawing2D.MatrixOrder.Append);
e.DrawImage(mCharImages[Key], 0, 0);
e.Flush();
}
return tmpImg;
}
}
static Generator()
{
HatchBrush sb = new HatchBrush(HatchStyle.Percent40, Color.Black, Color.Black);
foreach (char item in VALUE)
{
Bitmap bmp = new Bitmap(50, 50);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawString(new string(new char[] { item }), new Font("宋体", 24, FontStyle.Italic), sb, 2, 2);
}
mCharImages[item]= bmp;
}
mLine = new Bitmap(60, 4);
using (Graphics g = Graphics.FromImage(mLine))
{
g.FillRectangle(sb, 0, 0, 60, 3);
}
}
}
}