该验证码生成类集合了网上大部分的验证码生成类的精华,并多次改进,现在已经形成了可在生产环节中使用的验证码。
该验证码加入了背景噪点,背景噪点曲线和直线,背景噪点文字以及扭曲,调暗,模糊等。完全可以实现防识别。
按照国际惯例先贴张效果图吧:
#region 验证码生成类
/// <summary>
/// 验证码生成类
/// </summary>
public class ValidateCode
{
#region 定义和初始化配置字段
//用户存取验证码字符串
public string validationCode = String.Empty;
//生成的验证码字符串
public char[] chars = null;
/// <summary>
/// 获取系统生成的随机验证码
/// </summary>
public String ValidationCode
{
get { return validationCode; }
}
private Int32 validationCodeCount = 4;
/// <summary>
/// 获取和设置验证码字符串的长度
/// </summary>
public Int32 ValidationCodeCount
{
get { return validationCodeCount; }
set { validationCodeCount = value; }
}
Graphics dc = null;
private int bgWidth = 130;
/// <summary>
/// 验证码的宽度,默认为80
/// </summary>
public Int32 Width
{
get { return bgWidth; }
set { bgWidth = value; }
}
private int bgHeight = 40;
/// <summary>
/// 验证码的高度,默认为40
/// </summary>
public Int32 Height
{
get { return bgHeight; }
set { bgHeight = value; }
}
/* private string[] fontFace = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" };
/// <summary>
/// 验证码字体列表,默认为{ "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" }
/// </summary>
public String[] FontFace
{
get { return fontFace; }
set { fontFace = value; }
}*/
private int fontMinSize = 20;
/// <summary>
/// 验证码字体的最小值,默认为15,建议不小于15像素
/// </summary>
public Int32 FontMinSize
{
get { return fontMinSize; }
set { fontMinSize = value; }
}
private Int32 fontMaxSize = 25;
/// <summary>
/// 验证码字体的最大值,默认为20
/// </summary>
public Int32 FontMaxSize
{
get { return fontMaxSize; }
set { fontMaxSize = value; }
}
private Color[] fontColor = { };
/// <summary>
/// 验证码字体的颜色,默认为系统自动生成字体颜色
/// </summary>
public Color[] FontColor
{
get { return fontColor; }
set { fontColor = value; }
}
private Color backColor = Color.FromArgb(243, 255, 255);
/// <summary>
/// 验证码的背景色,默认为Color.FromArgb(243, 251, 254)
/// </summary>
public Color BackgroundColor
{
get { return backColor; }
set { backColor = value; }
}
private Int32 bezierCount = 3;
/// <summary>
/// 贝塞尔曲线的条数,默认为3条
/// </summary>
public Int32 BezierCount
{
get { return bezierCount; }
set { bezierCount = value; }
}
private Int32 lineCount = 3;
/// <summary>
/// 直线条数,默认为3条
/// </summary>
public Int32 LineCount
{
get { return lineCount; }
set { lineCount = value; }
}
Random random = new Random();
private String charCollection = "2,3,4,5,6,7,8,9,a,s,d,f,g,h,z,c,v,b,n,m,k,q,w,e,r,t,y,u,p,A,S,D,F,G,H,Z,C,V,B,N,M,K,Q,W,E,R,T,Y,U,P"; //定义验证码字符及出现频次 ,避免出现0 o j i l 1 x;
/// <summary>
/// 随机字符串列表,请使用英文状态下的逗号分隔。
/// </summary>
public String CharCollection
{
get { return charCollection; }
set { charCollection = value; }
}
private Int32 intCount = 4;
/// <summary>
/// 验证码字符串个数,默认为4个字符
/// </summary>
public Int32 IntCount
{
get { return intCount; }
set { intCount = value; }
}
private Boolean isPixel = true;
/// <summary>
/// 是否添加噪点,默认添加,噪点颜色为系统随机生成。
/// </summary>
public Boolean IsPixel
{
get { return isPixel; }
set { isPixel = value; }
}
private Boolean isRandString = true;
/// <summary>
/// 是否添加随机噪点字符串,默认添加
/// </summary>
public Boolean IsRandString
{
get { return isRandString; }
set { isRandString = value; }
}
/// <summary>
/// 随机背景字符串的个数
/// </summary>
public Int32 RandomStringCount
{
get;
set;
}
private Int32 randomStringFontSize = 9;
/// <summary>
/// 随机背景字符串的大小
/// </summary>
public Int32 RandomStringFontSize
{
get { return randomStringFontSize; }
set { randomStringFontSize = value; }
}
/// <summary>
/// 是否对图片进行扭曲
/// </summary>
public Boolean IsTwist
{
get;
set;
}
/// <summary>
/// 边框样式
/// </summary>
public enum BorderStyle
{
/// <summary>
/// 无边框
/// </summary>
None,
/// <summary>
/// 矩形边框
/// </summary>
Rectangle,
/// <summary>
/// 圆角边框
/// </summary>
RoundRectangle
}
private Int32 rotationAngle = 40;
/// <summary>
/// 验证码字符串随机转动的角度的最大值
/// </summary>
public Int32 RotationAngle
{
get { return rotationAngle; }
set { rotationAngle = value; }
}
/// <summary>
/// 设置或获取边框样式
/// </summary>
public BorderStyle Border
{
get;
set;
}
private Point[] strPoint = null;
private Double gaussianDeviation = 0;
/// <summary>
/// 对验证码图片进行高斯模糊的阀值,如果设置为0,则不对图片进行高斯模糊,该设置可能会对图片处理的性能有较大影响
/// </summary>
public Double GaussianDeviation
{
get { return gaussianDeviation; }
set { gaussianDeviation = value; }
}
private Int32 brightnessValue = 0;
/// <summary>
/// 对图片进行暗度和亮度的调整,如果该值为0,则不调整。该设置会对图片处理性能有较大影响
/// </summary>
public Int32 BrightnessValue
{
get { return brightnessValue; }
set { brightnessValue = value; }
}
#endregion
/// <summary>
/// 构造函数,用于初始化常用变量
/// </summary>
public void DrawValidationCode()
{
random = new Random(Guid.NewGuid().GetHashCode());
strPoint = new Point[validationCodeCount + 1];
if (gaussianDeviation < 0) gaussianDeviation = 0;
}
/// <summary>
/// 生成验证码
/// </summary>
/// <param name="target">用于存储图片的一般字节序列</param>
public byte[] CreateImage(string code)
{
MemoryStream target = new MemoryStream();
Bitmap bit = new Bitmap(bgWidth + 1, bgHeight + 1);
//写字符串
dc = Graphics.FromImage(bit);
dc.SmoothingMode = SmoothingMode.HighQuality;
dc.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; ;
dc.InterpolationMode = InterpolationMode.HighQualityBilinear;
dc.CompositingQuality = CompositingQuality.HighQuality;
try
{
dc.Clear(Color.White);
DrawValidationCode();
dc.DrawImageUnscaled(DrawBackground(), 0, 0);
dc.DrawImageUnscaled(DrawRandomString(code), 0, 0);
//对图片文字进行扭曲
bit = AdjustRippleEffect(bit, 5);
//对图片进行高斯模糊
if (gaussianDeviation > 0)
{
Gaussian gau = new Gaussian();
bit = gau.FilterProcessImage(gaussianDeviation, bit);
}
//进行暗度和亮度处理
if (brightnessValue != 0)
{
//对图片进行调暗处理
bit = AdjustBrightness(bit, brightnessValue);
}
bit.Save(target, ImageFormat.Jpeg);
//输出图片流
return target.ToArray();
}
finally
{
//brush.Dispose();
bit.Dispose();
dc.Dispose();
}
}
#region 画验证码背景,例如,增加早点,添加曲线和直线等
/// <summary>
/// 画验证码背景,例如,增加早点,添加曲线和直线等
/// </summary>
/// <returns></returns>
private Bitmap DrawBackground()
{
Bitmap bit = new Bitmap(bgWidth + 1, bgHeight + 1);
Graphics g = Graphics.FromImage(bit);
g.SmoothingMode = SmoothingMode.HighQuality;
g.Clear(Color.White);
Rectangle rectangle = new Rectangle(0, 0, bgWidth, bgHeight);
Brush brush = new SolidBrush(backColor);
g.FillRectangle(brush, rectangle);
//画噪点
if (isPixel)
{
g.DrawImageUnscaled(DrawRandomPixel(30), 0, 0);
}
g.DrawImageUnscaled(DrawRandBgString(), 0, 0);
//画曲线
//g.DrawImageUnscaled(DrawRandomBezier(bezierCount), 0, 0);
画直线
//g.DrawImageUnscaled(DrawRandomLine(lineCount), 0, 0);
//dc.DrawImageUnscaled(DrawStringline(), 0, 0);
if (Border == BorderStyle.Rectangle)
{
//绘制边框
g.DrawRectangle(new Pen(Color.FromArgb(90, 87, 46)), 0, 0, bgWidth, bgHeight);
}
else if (Border == BorderStyle.RoundRectangle)
{
//画圆角
DrawRoundRectangle(g, rectangle, Color.FromArgb(90, 87, 46), 1, 3);
}
return bit;
}
#endregion
#region 画正弦曲线
private Bitmap DrawTwist(Bitmap bmp, Int32 tWidth, Int32 tHeight, float angle, Color color)
{
//为了方便查看效果,在这里我定义了一个常量。
//它在定义数组的长度和for循环中都要用到。
int size = bgWidth;
double[] x = new double[size];
Bitmap b = new Bitmap(bmp.Width, bmp.Height);
b.MakeTransparent();
Graphics graphics = Graphics.FromImage(b);
Pen pen = new Pen(color);
//画正弦曲线的横轴间距参数。建议所用的值应该是 正数且是2的倍数。
//在这里采用2。
int val = 2;
float temp = 0.0f;
//把画布下移100。为什么要这样做,只要你把这一句给注释掉,运行一下代码,
//你就会明白是为什么?
graphics.TranslateTransform(0, 100);
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
for (int i = 0; i < size; i++)
{
//改变tWidth,实现正弦曲线宽度的变化。
//改tHeight,实现正弦曲线高度的变化。
x[i] = Math.Sin(2 * Math.PI * i / tWidth) * tHeight;
graphics.DrawLine(pen, i * val, temp, i * val + val / 2, (float)x[i]);
temp = (float)x[i];
}
graphics.RotateTransform(60, MatrixOrder.Prepend);
//旋转图片
// b = KiRotate(b, angle, Color.Transparent);
return b;
}
#endregion
#region 正弦曲线Wave扭曲图片
/// <summary>
/// 正弦曲线Wave扭曲图片
/// </summary>
/// <param name="srcBmp">图片路径</param>
/// <param name="bXDir">如果扭曲则选择为True</param>
/// <param name="dMultValue">波形的幅度倍数,越大扭曲的程度越高,一般为3</param>
/// <param name="dPhase">波形的起始相位,取值区间[0-2*PI)</param>
/// <returns></returns>
public Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase)
{
System.Drawing.Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
double PI2 = 6.283185307179586476925286766559;