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 }