验证码

  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 }

 

posted @ 2013-05-21 10:10  liaohz  阅读(218)  评论(0编辑  收藏  举报