code:
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 HyeyClass.Common { /// <summary> /// ClassName:DrawValidateImg /// Auther:Hyey.wl /// Time:2010-04-30 /// Other: /// DrawValidateImg 的摘要说明。 /// </summary> public class DrawValidateImg { /// <summary> /// 无参构造 /// Initializes a new instance of the <see cref="DrawValidateImg"/> class. /// </summary> public DrawValidateImg() { // // TODO: 在此处添加构造函数逻辑 // } /// <summary> /// 带有生成字符个数的构造 /// Initializes a new instance of the <see cref="DrawValidateImg"/> class. /// </summary> /// <param name="charNum">The char num.验证码中包含随机字符的个数</param> public DrawValidateImg(int charNum) { this.CharNum = charNum; } /// <summary> /// 带有验证码图片宽度和高度的构造 /// Initializes a new instance of the <see cref="DrawValidateImg"/> class. /// </summary> /// <param name="width">The width.验证码图片宽度</param> /// <param name="height">The height.验证码图片高度</param> public DrawValidateImg(int width ,int height) { this.width = width; this.height = height; } /// <summary> /// 带有生成字符个数,验证码图片宽度和高度的构造 /// Initializes a new instance of the <see cref="DrawValidateImg"/> class. /// </summary> /// <param name="charNum">The char num.验证码中包含随机字符的个数</param> /// <param name="width">The width.验证码图片宽度</param> /// <param name="height">The height.验证码图片高度</param> public DrawValidateImg(int charNum ,int width ,int height) { this.CharNum = charNum; this.width = width; this.height = height; } /// <summary> /// 验证码中字符个数 /// </summary> int charNum = 5; //默认字符个数为5 /// <summary> /// 字数 /// Gets or sets the char num. /// </summary> /// <value>The char num.</value> public int CharNum { get { return charNum; } set { charNum = value; } } /// <summary> /// 字号 /// </summary> int fontSize =20; /// <summary> /// 字号 /// Gets the size of the font. /// </summary> /// <value>The size of the font.</value> public int FontSize { get { return fontSize; } } /// <summary> /// 图片宽度 /// </summary> int width=200; /// <summary> /// Gets the width. /// </summary> /// <value>The width.</value> public int Width { get { return width; } } /// <summary> /// 图片高度 /// </summary> int height=50; /// <summary> /// Gets or sets the height. /// </summary> /// <value>The height.</value> public int Height { get { return height; } set { height = value; } } /// <summary> /// 随机生成的字符串 /// </summary> string validStr=""; /// <summary> /// Gets or sets the valid STR. /// 随机生成的字符串 /// </summary> /// <value>The valid STR.</value> public string ValidStr { get { return validStr; } set { validStr = value; } } /// <summary> /// 产生指定个数的随机字符串,默认字符个数为5 /// </summary> void GetValidateCode() { Random rd = new Random(); //创建随机数对象 //产生由 charNum 个字母或数字组成的一个字符串 string str = "ABCDEFGHJKLMNPQRSTUVWYZ23456789";//共31个字符,除 l,o,x,I,O,X,1,0 的所有数字和大写字母 for (int i = 0; i < charNum; i++) { validStr = validStr + str[rd.Next(30)];//返回0到54 } } /// <summary> /// 由随机字符串,随即颜色背景,和随机线条产生的Image /// 返回 MemoryStream /// </summary> /// <returns>MemoryStream</returns> public MemoryStream GetImgWithValidateCode() { //产生随机字符串 GetValidateCode(); //声明一个位图对象 Bitmap bitMap = null; //声明一个绘图画面 Graphics gph = null; //创建内存流 using(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)); //gph.Clear(Color.White); //产生随机干扰线条 // 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)); PointF Cpoint1=new PointF(5,5); Random rnd1 = new Random(); int x1 = 0, y1 = 0; //通过循环,绘制每个字符, for (int i = 0; i < validStr.Length; i++) { //随机字符位置 x1 = rnd1.Next(10)+40*i; y1 = rnd1.Next(bitMap.Height/4); Cpoint1 = new PointF(x1,y1); //随机字符颜色,应根据背景作适当调整以免显示模糊不清 SolidBrush sb = new SolidBrush(Color.FromArgb(rnd1.Next(100), rnd1.Next(100), rnd1.Next(100))); //Font textFont = new Font(fontFamily[random.Next(10)], fontSize, FontStyle.Bold);//字体随机,字号大小30,加粗 Font textFont = new Font("Arial",35 , FontStyle.Bold);//字体随机,字号大小30,加粗 //随机倾斜字符 gph.TranslateTransform(10, 0); Matrix transform = gph.Transform; transform.Shear(Convert.ToSingle( rnd1.NextDouble()-0.5),0.001f); gph.Transform = transform; //每次循环绘制一个字符,设置字体格式,画笔颜色,字符相对画布的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); gph.DrawString(validStr.Substring(i, 1), textFont, sb, Cpoint1); gph.ResetTransform(); } //扭曲图片 //bitMap=TwistImage(bitMap, true, random.Next(3,5),random.Next(3)); //画图片的前景噪音点 // for (int i = 0; i < 10; i++) // { // int x = random.Next(bitMap.Width); // int y = random.Next(bitMap.Height); // bitMap.SetPixel(x, y, Color.White); // } //画图片的边框线 gph.DrawRectangle(new Pen(Color.Black,2), 0, 0, bitMap.Width - 1, bitMap.Height - 1); try { bitMap.Save(memStream, ImageFormat.Gif); } catch (Exception ex) { System.Windows.Forms.MessageBox.Show(ex.Message); } bitMap.Dispose(); // Image img = Image.FromStream(memStream); // gph.DrawImage(img, 50, 20, width, 10); //gph.Dispose(); //return img; return memStream; } } /// <summary> /// 产生一种 R,G,B 均大于 colorBase 随机颜色,以确保颜色不会过深 /// </summary> /// <param name="colorBase">The color base.</param> /// <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 name="srcBmp">The SRC BMP.</param> /// <param name="bXDir">if set to <c>true</c> [b X dir].</param> /// <param name="dMultValue">The d mult value.</param> /// <param name="dPhase">The d phase.</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 name="inputValCode">待判断的验证码</param> /// <returns>正确返回 true,错误返回 false</returns> public bool IsRight(string inputValCode) { if (validStr.ToUpper().Equals(inputValCode.ToUpper()))//无论输入大小写都转换为大些判断 { return true; } else { return false; } } } }