验证码
1 using System; 2 using System.Drawing; 3 using System.Drawing.Drawing2D; 4 using System.Drawing.Imaging; 5 using System.IO; 6 using System.Web; 7 using System.Web.SessionState; 8 9 namespace WebApplication1 10 { 11 /// <summary> 12 /// ValidateCode 的摘要说明 13 /// </summary> 14 public class ValidateCode : IHttpHandler, IRequiresSessionState 15 { 16 private const string strValidateCodeBound = "ABCDEFGHIJKLMNPQRSTUVWXYZ23456789"; 17 private static string[] Fonts = new string[] { "Helvetica", 18 "Geneva", 19 "sans-serif", 20 "Verdana", 21 "Times New Roman", 22 "Courier New", 23 "Arial" 24 }; 25 26 public void ProcessRequest(HttpContext context) 27 { 28 string str_ValidateCode = GetRandomString(6); 29 30 context.Session["ValidateCode"] = str_ValidateCode; 31 32 byte[] bt = CreateImage(str_ValidateCode); 33 34 context.Response.ClearContent(); 35 context.Response.ContentType = "image/Png"; 36 context.Response.BinaryWrite(bt); 37 context.Response.End(); 38 } 39 40 /// <summary> 41 /// Generate random string 42 /// </summary> 43 private string GetRandomString(int int_NumberLength) 44 { 45 string valString = string.Empty; 46 Random theRandomNumber = new Random((int)DateTime.Now.Ticks); 47 48 for (int int_index = 0; int_index < int_NumberLength; int_index++) 49 valString += strValidateCodeBound[theRandomNumber.Next(strValidateCodeBound.Length - 1)].ToString(); 50 51 return valString; 52 } 53 54 /// <summary> 55 /// Generate random Color 56 /// </summary> 57 private Color GetRandomColor(int seed) 58 { 59 Random RandomNum_First = new Random(seed); 60 61 int int_Red = RandomNum_First.Next(256); 62 int int_Green = RandomNum_First.Next(256); 63 int int_Blue = RandomNum_First.Next(256); 64 65 return Color.FromArgb(int_Red, int_Green, int_Blue); 66 } 67 68 /// <summary> 69 /// Create Validation Code Image 70 /// </summary> 71 private byte[] CreateImage(string str_ValidateCode) 72 { 73 int int_ImageWidth = str_ValidateCode.Length * 22; 74 Random newRandom = new Random(); 75 76 Bitmap theBitmap = new Bitmap(int_ImageWidth + 6, 38); 77 78 //画字符 79 Graphics theGraphics = Graphics.FromImage(theBitmap); 80 81 theGraphics.Clear(Color.White); 82 83 for (int int_index = 0; int_index < str_ValidateCode.Length; int_index++) 84 { 85 Matrix X = new Matrix(); 86 X.Shear((float)newRandom.Next(0, 300) / 1000 - 0.25f, (float)newRandom.Next(0, 100) / 1000 - 0.05f); 87 theGraphics.Transform = X; 88 string str_char = str_ValidateCode.Substring(int_index, 1); 89 System.Drawing.Drawing2D.LinearGradientBrush newBrush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, theBitmap.Width, theBitmap.Height), GetRandomColor(newRandom.Next(1, 10)), GetRandomColor(newRandom.Next(20, 30)), 1.2f, true); 90 Point thePos = new Point(int_index * 21 + 1 + newRandom.Next(3), 1 + newRandom.Next(13)); 91 92 Font theFont = new Font(Fonts[newRandom.Next(Fonts.Length - 1)], newRandom.Next(14, 18), FontStyle.Bold); 93 94 theGraphics.DrawString(str_char, theFont, newBrush, thePos); 95 } 96 97 theGraphics.Dispose(); 98 99 //扭曲 100 theBitmap = TwistImage(theBitmap, true, 8, 4); 101 102 //画噪点、线和边框 103 Graphics theG = Graphics.FromImage(theBitmap); 104 drawPoint(theBitmap, newRandom); 105 drawLine(theG, theBitmap, newRandom); 106 theG.DrawRectangle(new Pen(Color.LightGray, 1), 0, 0, theBitmap.Width - 1, theBitmap.Height - 1); 107 108 MemoryStream ms = new MemoryStream(); 109 theBitmap.Save(ms, ImageFormat.Png); 110 111 theBitmap.Dispose(); 112 113 return ms.ToArray(); 114 } 115 116 /// <summary> 117 /// Draw Line for noise 118 /// </summary> 119 private void drawLine(Graphics gfc, Bitmap img, Random ran) 120 { 121 for (int i = 0; i < 10; i++) 122 { 123 int x1 = ran.Next(img.Width); 124 int y1 = ran.Next(img.Height); 125 int x2 = ran.Next(img.Width); 126 int y2 = ran.Next(img.Height); 127 gfc.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2); 128 } 129 } 130 131 /// <summary> 132 /// Draw Point for noise 133 /// </summary> 134 private void drawPoint(Bitmap img, Random ran) 135 { 136 for (int i = 0; i < 30; i++) 137 { 138 int x = ran.Next(img.Width); 139 int y = ran.Next(img.Height); 140 img.SetPixel(x, y, Color.FromArgb(ran.Next())); 141 } 142 143 } 144 145 /// <summary> 146 /// 正弦曲线Wave扭曲图片 147 /// </summary> 148 /// <param name="srcBmp">图片路径</param> 149 /// <param name="bXDir">如果扭曲则选择为True</param> 150 /// <param name="dMultValue">波形的幅度倍数,越大扭曲的程度越高,一般为3</param> 151 /// <param name="dPhase">波形的起始相位,取值区间[0-2*PI)</param> 152 /// <returns></returns> 153 public Bitmap TwistImage(Bitmap srcBmp, bool bXDir, double dMultValue, double dPhase) 154 { 155 double PI2 = Math.PI * 2; 156 157 System.Drawing.Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height); 158 159 // 将位图背景填充为白色 160 System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(destBmp); 161 graph.FillRectangle(new SolidBrush(System.Drawing.Color.White), 0, 0, destBmp.Width, destBmp.Height); 162 graph.Dispose(); 163 164 double dBaseAxisLen = bXDir ? (double)destBmp.Height : (double)destBmp.Width; 165 166 for (int i = 0; i < destBmp.Width; i++) 167 { 168 for (int j = 0; j < destBmp.Height; j++) 169 { 170 double dx = 0; 171 dx = bXDir ? (PI2 * (double)j) / dBaseAxisLen : (PI2 * (double)i) / dBaseAxisLen; 172 dx += dPhase; 173 double dy = Math.Sin(dx); 174 175 // 取得当前点的颜色 176 int nOldX = 0, nOldY = 0; 177 nOldX = bXDir ? i + (int)(dy * dMultValue) : i; 178 nOldY = bXDir ? j : j + (int)(dy * dMultValue); 179 180 System.Drawing.Color color = srcBmp.GetPixel(i, j); 181 if (nOldX >= 0 && nOldX < destBmp.Width 182 && nOldY >= 0 && nOldY < destBmp.Height) 183 { 184 destBmp.SetPixel(nOldX, nOldY, color); 185 } 186 } 187 } 188 return destBmp; 189 } 190 191 192 public bool IsReusable 193 { 194 get 195 { 196 return false; 197 } 198 } 199 } 200 }