验证码字符个数、生成图片宽度、高度自定均可由构造方法自定,无参构造生成默认字符个数和默认大小的Image,方法 GetImgWithValidateCode()返回生成的验证码图片,方法 IsRight(string inputValCode) 判断用户输入的验证码 inputValCode与
图片显示的字符是否一致,不区分大小写
- using System;
- using System.IO;
- using System.Data;
- using System.Configuration;
- using System.Collections;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Drawing.Drawing2D;
- namespace DrawValidateImageLib
- {
- public class DrawValImg
- {
- /// <summary>
- /// 无参构造
- /// </summary>
- public DrawValImg() { }
- /// <summary>
- /// 带有生成字符个数的构造
- /// </summary>
- /// <param >验证码中包含随机字符的个数</param>
- public DrawValImg(int charNum)
- {
- this.CharNum = charNum;
- }
- /// <summary>
- /// 带有验证码图片宽度和高度的构造
- /// </summary>
- /// <param >验证码图片宽度</param>
- /// <param >验证码图片高度</param>
- public DrawValImg(int width,int height)
- {
- this.width = width;
- this.height = height;
- }
- /// <summary>
- /// 带有生成字符个数,验证码图片宽度和高度的构造
- /// </summary>
- /// <param >验证码中包含随机字符的个数</param>
- /// <param >验证码图片宽度</param>
- /// <param >验证码图片高度</param>
- public DrawValImg(int charNum,int width,int height)
- {
- this.CharNum = charNum;
- this.width = width;
- this.height = height;
- }
- /// <summary>
- /// 验证码中字符个数
- /// </summary>
- int charNum = 5; //默认字符个数为5
- public int CharNum
- {
- get { return charNum; }
- set { charNum = value; }
- }
- /// <summary>
- /// 字号
- /// </summary>
- int fontSize = 20;
- public int FontSize
- {
- get { return fontSize; }
- }
- /// <summary>
- /// 图片宽度
- /// </summary>
- int width=200;
- public int Width
- {
- get { return width; }
- }
- /// <summary>
- /// 图片高度
- /// </summary>
- int height=45;
- public int Height
- {
- get { return height; }
- set { height = value; }
- }
- /// <summary>
- /// 随机生成的字符串
- /// </summary>
- string validStr="";
- public string ValidStr
- {
- get { return validStr; }
- set { validStr = value; }
- }
- /// <summary>
- /// 产生指定个数的随机字符串,默认字符个数为5
- /// </summary>
- void GetValidateCode()
- {
- Random rd = new Random(); //创建随机数对象
- //产生由 charNum 个字母或数字组成的一个字符串
- string str = "abcdefghijkmnpqrstuvwyzABCDEFGHJKLMNPQRSTUVWYZ23456789田国兴";//共57个字符,除 l,o,x,I,O,X,1,0 的所有数字和大写字母
- for (int i = 0; i < charNum; i++)
- {
- validStr = validStr + str.Substring(rd.Next(57), 1);//返回0到56共57个
- }
- }
- /// <summary>
- /// 由随机字符串,随即颜色背景,和随机线条产生的Image
- /// </summary>
- /// <returns>Image</returns>
- public Image GetImgWithValidateCode()//返回 Image
- {
- //产生随机字符串
- GetValidateCode();
- //声明一个位图对象
- Bitmap bitMap = null;
- //声明一个绘图画面
- Graphics gph = null;
- //创建内存流
- MemoryStream memStream = new MemoryStream();
- Random random = new Random();
- //由给定的需要生成字符串中字符个数 CharNum, 图片宽度 Width 和高度 Height 确定字号 FontSize,
- //确保不因字号过大而不能全部显示在图片上
- int fontWidth=(int)Math.Round(width/(charNum+2)/1.3);
- int fontHeight=(int)Math.Round(height/1.5);
- //字号取二者中小者,以确保所有字符能够显示,并且字符的下半部分也能显示
- fontSize = fontWidth <= fontHeight ? fontWidth : fontHeight;
- //创建位图对象
- bitMap = new Bitmap(width+FontSize,height);
- //根据上面创建的位图对象创建绘图图面
- gph = Graphics.FromImage(bitMap);
- //设定验证码图片背景色
- gph.Clear(GetControllableColor(200));
- //产生随机干扰线条
- for (int i = 0; i < 10; i++)
- {
- Pen backPen = new Pen(GetControllableColor(100), 2);
- //线条起点
- int x = random.Next(width);
- int y = random.Next(height);
- //线条终点
- int x2 = random.Next(width);
- int y2 = random.Next(height);
- //划线
- gph.DrawLine(backPen, x, y, x2, y2);
- }
- //定义一个含10种字体的数组
- String fontFamily ={ "Arial", "Verdana", "Comic Sans MS", "Impact", "Haettenschweiler",
- "Lucida Sans Unicode", "Garamond", "Courier New", "Book Antiqua", "Arial Narrow" };
- SolidBrush sb = new SolidBrush(GetControllableColor(0));
- //通过循环,绘制每个字符,
- for (int i = 0; i < validStr.Length; i++)
- {
- Font textFont = new Font(fontFamily[random.Next(10)], fontSize, FontStyle.Bold);//字体随机,字号大小30,加粗
- //每次循环绘制一个字符,设置字体格式,画笔颜色,字符相对画布的X坐标,字符相对画布的Y坐标
- int space = (int)Math.Round((double)((width - fontSize * (CharNum + 2)) / CharNum));
- //纵坐标
- int y = (int)Math.Round((double)((height - fontSize)/3));
- gph.DrawString(validStr.Substring(i, 1), textFont, sb, fontSize + i * (fontSize + space), y);
- }
- //扭曲图片
- bitMap=TwistImage(bitMap, true, random.Next(3,5),random.Next(3));
- try
- {
- bitMap.Save(memStream, ImageFormat.Gif);
- }
- catch (Exception ex)
- {
- System.Windows.Forms.MessageBox.Show(ex.Message);
- }
- //gph.Dispose();
- bitMap.Dispose();
- Image img = Image.FromStream(memStream);
- gph.DrawImage(img, 50, 20, width, 10);
- return img;
- }
- /// <summary>
- /// 产生一种 R,G,B 均大于 colorBase 随机颜色,以确保颜色不会过深
- /// </summary>
- /// <returns>背景色</returns>
- Color GetControllableColor(int colorBase)
- {
- Color color=Color.Black;
- if (colorBase > 200)
- {
- System.Windows.Forms.MessageBox.Show("可控制颜色参数大于200,颜色默认位黑色");
- }
- Random random = new Random();
- //确保 R,G,B 均大于 colorBase,这样才能保证背景色较浅
- color= Color.FromArgb(random.Next(56) + colorBase, random.Next(56) + colorBase, random.Next(56) + colorBase);
- return color;
- }
- /// <summary>
- /// 扭曲图片
- /// </summary>
- /// <param ></param>
- /// <param ></param>
- /// <param ></param>
- /// <param ></param>
- /// <returns></returns>
- Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase)
- {
- int leftMargin = 0;
- int rightMargin = 0;
- int topMargin = 0;
- int bottomMargin = 0;
- //float PI = 3.14159265358979f;
- float PI2 = 6.28318530717959f;
- Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
- double dBaseAxisLen = bXDir ? Convert.ToDouble(destBmp.Height) : Convert.ToDouble(destBmp.Width);
- for (int i = 0; i < destBmp.Width; i++)
- {
- for (int j = 0; j < destBmp.Height; j++)
- {
- double dx = 0;
- dx = bXDir ? PI2 * Convert.ToDouble(j) / dBaseAxisLen : PI2 * Convert.ToDouble(i) / dBaseAxisLen;
- dx += dPhase;
- double dy = Math.Sin(dx);
- //取得当前点的颜色
- int nOldX = 0;
- int nOldY = 0;
- nOldX = bXDir ? i + Convert.ToInt32(dy * dMultValue) : i;
- nOldY = bXDir ? j : j + Convert.ToInt32(dy * dMultValue);
- System.Drawing.Color color = srcBmp.GetPixel(i, j);
- if (nOldX >= leftMargin && nOldX < destBmp.Width - rightMargin && nOldY >= bottomMargin && nOldY < destBmp.Height - topMargin)
- {
- destBmp.SetPixel(nOldX, nOldY, color);
- }
- }
- }
- return destBmp;
- }
- /// <summary>
- /// 判断验证码是否正确
- /// </summary>
- /// <param >待判断的验证码</param>
- /// <returns>正确返回 true,错误返回 false</returns>
- public bool IsRight(string inputValCode)
- {
- if (validStr.ToUpper().Equals(inputValCode.ToUpper()))//无论输入大小写都转换为大些判断
- {
- return true;
- }
- else
- {
- return false;
- }
- }