C#验证码

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;

			}

		}

	}

}



你可能感兴趣的:(验证码)