网上有许多关于验证码生成的类.鉴于以后方便.自写了一个波形验证码,其中波形操作参考了.无刷新仿google波形扭曲彩色Asp.net验证码. 代码如下
代码
1
2 /// <summary>
3 /// 验证码操作类
4 /// </summary>
5 public class VerifyCode
6 {
7 private string _generateCode = string .Empty;
8 private const double PI2 = 6.283185307179586476925286766559 ;
9
10 /// <summary>
11 /// 绘制的符号数量
12 /// </summary>
13 /// <value> The code count. </value>
14 public int CodeCount { get ; set ; }
15
16 /// <summary>
17 /// 生成的验证码
18 /// </summary>
19 /// <value> The generate code. </value>
20 public string GenerateCode { get { return _generateCode; } }
21
22 /// <summary>
23 /// 验证码字体
24 /// </summary>
25 /// <value> The font family. </value>
26 public FontFamily FontFamily { get ; set ; }
27
28 /// <summary>
29 /// 字体大小
30 /// </summary>
31 /// <value> The size of the font. </value>
32 public int FontSize { get ; set ; }
33
34 /// <summary>
35 /// 是否扭曲
36 /// </summary>
37 /// <value><c> true </c> if wave; otherwise, <c> false </c> . </value>
38 public bool Wave { get ; set ; }
39
40 /// <summary>
41 /// 扭曲方向,true为纵向,false为横向
42 /// </summary>
43 /// <value><c> true </c> if [wave dir]; otherwise, <c> false </c> . </value>
44 public bool WaveDirc { get ; set ; }
45
46 /// <summary>
47 /// 波形扭曲幅度
48 /// </summary>
49 /// <value> The wave value. </value>
50 public int WaveValue { get ; set ; }
51
52 /// <summary>
53 /// 波形起始相位
54 /// </summary>
55 /// <value> The wave phase. </value>
56 public double WavePhase { get ; set ; }
57
58 public VerifyCode( int codeCount)
59 {
60 CodeCount = codeCount;
61 FontFamily = new FontFamily( " Arial " );
62 FontSize = 40 ;
63 Wave = true ;
64 WaveDirc = false ;
65 WaveValue = 12 ;
66 WavePhase = 10 ;
67 }
68
69 /// <summary>
70 /// 创建图片并输出
71 /// </summary>
72 /// <param name="context"> The context. </param>
73 public void CreateImage(HttpContext context)
74 {
75 CreateCheckCodeImage(CreateRandomCode(CodeCount), context);
76 }
77
78 /// <summary>
79 /// 生成随机数
80 /// </summary>
81 /// <param name="codeCount"> The code count. </param>
82 /// <returns></returns>
83 private string CreateRandomCode( int codeCount)
84 {
85 int number;
86
87 Random random = new Random();
88
89 for ( int i = 0 ; i < codeCount; i ++ )
90 {
91 // 随机整数
92 number = random.Next();
93
94 // 字符从0-9,A-Z中随机产生,对应的ASCII码为 48-57,65-90
95 number = number % 36 ;
96
97 if (number < 10 )
98 {
99 number += 48 ;
100 }
101 else
102 {
103 number += 55 ;
104 }
105 _generateCode += (( char )number).ToString();
106 }
107 return _generateCode;
108 }
109
110 /// <summary>
111 /// 生成验证码图片
112 /// </summary>
113 /// <param name="checkCode"> The check code. </param>
114 /// <param name="context"> The context. </param>
115 private void CreateCheckCodeImage( string checkCode, HttpContext context)
116 {
117 // 若验证码为空,直接返回
118 if ( string .IsNullOrEmpty(checkCode))
119 return ;
120 // 根据验证码的长度确定输出图片的长度
121 Bitmap image = new Bitmap(( int )Math.Ceiling((checkCode.Length * (FontSize + 4.5 ))), FontSize * 2 );
122 // 创建Graphs对象
123 Graphics g = Graphics.FromImage(image);
124
125 try
126 {
127 Random random = new Random();
128 // 清空图片背景色
129 g.Clear(Color.White);
130 // 画图片的背景噪音线25条
131 for ( int i = 0 ; i < 25 ; i ++ )
132 {
133 // 噪音线的坐标(x1,y1),(x2,y2)
134 int x1 = random.Next(image.Width);
135 int x2 = random.Next(image.Width);
136 int y1 = random.Next(image.Height);
137 int y2 = random.Next(image.Height);
138 // 用银色画出噪音线
139 g.DrawLine( new Pen(Color.Silver), x1, y1, x2, y2);
140 }
141 // 输出图片中的验证码
142 Font font = new Font(FontFamily, FontSize, (FontStyle.Bold | FontStyle.Italic));
143 // 线性渐变笔刷
144 LinearGradientBrush brush = new LinearGradientBrush( new Rectangle( 0 , 0 , image.Width, image.Height), Color.Green, RandomColor(), 1.2f , true );
145 g.DrawString(checkCode, font, brush, 0 , 0 );
146
147 // 图片的前景噪音点
148 for ( int i = 0 ; i < 50 ; i ++ )
149 {
150 int x = random.Next(image.Width);
151 int y = random.Next(image.Height);
152 image.SetPixel(x, y, Color.FromArgb(random.Next()));
153 }
154 // 画图片的边框线
155 g.DrawRectangle( new Pen(Color.Peru), 0 , 0 , image.Width - 1 , image.Height - 1 );
156
157 if (Wave) // 是否扭曲
158 image = TwistImage(image, WaveDirc, WaveValue, WavePhase);
159
160 // 创建内存刘用于输出图片
161 using (MemoryStream ms = new MemoryStream())
162 {
163 // 图片格式指定为JPG
164 image.Save(ms, ImageFormat.Jpeg);
165 // 清空缓冲区流中的所有输出
166 context.Response.ClearContent();
167 // 输出流的HTTP MIME类型设置
168 context.Response.ContentType = " image/Jpeg " ;
169 // 输出图片的二进制流
170 context.Response.BinaryWrite(ms.ToArray());
171 }
172 }
173 finally
174 {
175 g.Dispose();
176 image.Dispose();
177 }
178 }
179
180 /// <summary>
181 /// 正弦曲线Wave扭曲图片
182 /// </summary>
183 /// <param name="srcBmp"> 源图片. </param>
184 /// <param name="bxDir"> 扭曲方向 </param>
185 /// <param name="dMultValue"> 波形的幅度倍数,越大扭曲的程度越高,一般为3 </param>
186 /// <param name="dPhase"> 波形的起始相位,取值区间[0-2*PI] </param>
187 /// <returns></returns>
188 private Bitmap TwistImage(Bitmap srcBmp, bool bxDir, double dMultValue, double dPhase)
189 {
190 Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
191
192 // 将位图背景填充为白色
193 Graphics graph = Graphics.FromImage(destBmp);
194 graph.FillRectangle( new SolidBrush(Color.White), 0 , 0 , destBmp.Width, destBmp.Height);
195 graph.Dispose();
196
197 double dBaseAxisLen = bxDir ? ( double )destBmp.Height : ( double )destBmp.Width;
198
199 for ( int i = 0 ; i < destBmp.Width; i ++ )
200 {
201 for ( int j = 0 ; j < destBmp.Height; j ++ )
202 {
203 double dx = 0 ;
204 dx = bxDir ? (PI2 * ( double )j) / dBaseAxisLen : (PI2 * ( double )i) / dBaseAxisLen;
205 dx += dPhase;
206 double dy = Math.Sin(dx);
207
208 // 取得当前点的颜色
209 int nOldX = 0 , nOldY = 0 ;
210 nOldX = bxDir ? i + ( int )(dy * dMultValue) : i;
211 nOldY = bxDir ? j : j + ( int )(dy * dMultValue);
212
213 Color color = srcBmp.GetPixel(i, j);
214 if (nOldX >= 0 && nOldX < destBmp.Width && nOldY >= 0 && nOldY < destBmp.Height)
215 {
216 destBmp.SetPixel(nOldX, nOldY, color);
217 }
218 }
219 }
220 return destBmp;
221 }
222
223 /// <summary>
224 /// 随机颜色
225 /// </summary>
226 /// <returns></returns>
227 private Color RandomColor()
228 {
229 Random randomNumFirst = new Random(DateTime.Now.Millisecond);
230 Random randomNumSencond = new Random(DateTime.Now.Millisecond);
231
232 int red = randomNumFirst.Next( 256 );
233 int green = randomNumSencond.Next( 256 );
234 int blue = (red + green > 400 ) ? 0 : 400 - red - green;
235 blue = blue > 255 ? 255 : blue;
236 return Color.FromArgb(red, green, blue);
237 }
238 }
2 /// <summary>
3 /// 验证码操作类
4 /// </summary>
5 public class VerifyCode
6 {
7 private string _generateCode = string .Empty;
8 private const double PI2 = 6.283185307179586476925286766559 ;
9
10 /// <summary>
11 /// 绘制的符号数量
12 /// </summary>
13 /// <value> The code count. </value>
14 public int CodeCount { get ; set ; }
15
16 /// <summary>
17 /// 生成的验证码
18 /// </summary>
19 /// <value> The generate code. </value>
20 public string GenerateCode { get { return _generateCode; } }
21
22 /// <summary>
23 /// 验证码字体
24 /// </summary>
25 /// <value> The font family. </value>
26 public FontFamily FontFamily { get ; set ; }
27
28 /// <summary>
29 /// 字体大小
30 /// </summary>
31 /// <value> The size of the font. </value>
32 public int FontSize { get ; set ; }
33
34 /// <summary>
35 /// 是否扭曲
36 /// </summary>
37 /// <value><c> true </c> if wave; otherwise, <c> false </c> . </value>
38 public bool Wave { get ; set ; }
39
40 /// <summary>
41 /// 扭曲方向,true为纵向,false为横向
42 /// </summary>
43 /// <value><c> true </c> if [wave dir]; otherwise, <c> false </c> . </value>
44 public bool WaveDirc { get ; set ; }
45
46 /// <summary>
47 /// 波形扭曲幅度
48 /// </summary>
49 /// <value> The wave value. </value>
50 public int WaveValue { get ; set ; }
51
52 /// <summary>
53 /// 波形起始相位
54 /// </summary>
55 /// <value> The wave phase. </value>
56 public double WavePhase { get ; set ; }
57
58 public VerifyCode( int codeCount)
59 {
60 CodeCount = codeCount;
61 FontFamily = new FontFamily( " Arial " );
62 FontSize = 40 ;
63 Wave = true ;
64 WaveDirc = false ;
65 WaveValue = 12 ;
66 WavePhase = 10 ;
67 }
68
69 /// <summary>
70 /// 创建图片并输出
71 /// </summary>
72 /// <param name="context"> The context. </param>
73 public void CreateImage(HttpContext context)
74 {
75 CreateCheckCodeImage(CreateRandomCode(CodeCount), context);
76 }
77
78 /// <summary>
79 /// 生成随机数
80 /// </summary>
81 /// <param name="codeCount"> The code count. </param>
82 /// <returns></returns>
83 private string CreateRandomCode( int codeCount)
84 {
85 int number;
86
87 Random random = new Random();
88
89 for ( int i = 0 ; i < codeCount; i ++ )
90 {
91 // 随机整数
92 number = random.Next();
93
94 // 字符从0-9,A-Z中随机产生,对应的ASCII码为 48-57,65-90
95 number = number % 36 ;
96
97 if (number < 10 )
98 {
99 number += 48 ;
100 }
101 else
102 {
103 number += 55 ;
104 }
105 _generateCode += (( char )number).ToString();
106 }
107 return _generateCode;
108 }
109
110 /// <summary>
111 /// 生成验证码图片
112 /// </summary>
113 /// <param name="checkCode"> The check code. </param>
114 /// <param name="context"> The context. </param>
115 private void CreateCheckCodeImage( string checkCode, HttpContext context)
116 {
117 // 若验证码为空,直接返回
118 if ( string .IsNullOrEmpty(checkCode))
119 return ;
120 // 根据验证码的长度确定输出图片的长度
121 Bitmap image = new Bitmap(( int )Math.Ceiling((checkCode.Length * (FontSize + 4.5 ))), FontSize * 2 );
122 // 创建Graphs对象
123 Graphics g = Graphics.FromImage(image);
124
125 try
126 {
127 Random random = new Random();
128 // 清空图片背景色
129 g.Clear(Color.White);
130 // 画图片的背景噪音线25条
131 for ( int i = 0 ; i < 25 ; i ++ )
132 {
133 // 噪音线的坐标(x1,y1),(x2,y2)
134 int x1 = random.Next(image.Width);
135 int x2 = random.Next(image.Width);
136 int y1 = random.Next(image.Height);
137 int y2 = random.Next(image.Height);
138 // 用银色画出噪音线
139 g.DrawLine( new Pen(Color.Silver), x1, y1, x2, y2);
140 }
141 // 输出图片中的验证码
142 Font font = new Font(FontFamily, FontSize, (FontStyle.Bold | FontStyle.Italic));
143 // 线性渐变笔刷
144 LinearGradientBrush brush = new LinearGradientBrush( new Rectangle( 0 , 0 , image.Width, image.Height), Color.Green, RandomColor(), 1.2f , true );
145 g.DrawString(checkCode, font, brush, 0 , 0 );
146
147 // 图片的前景噪音点
148 for ( int i = 0 ; i < 50 ; i ++ )
149 {
150 int x = random.Next(image.Width);
151 int y = random.Next(image.Height);
152 image.SetPixel(x, y, Color.FromArgb(random.Next()));
153 }
154 // 画图片的边框线
155 g.DrawRectangle( new Pen(Color.Peru), 0 , 0 , image.Width - 1 , image.Height - 1 );
156
157 if (Wave) // 是否扭曲
158 image = TwistImage(image, WaveDirc, WaveValue, WavePhase);
159
160 // 创建内存刘用于输出图片
161 using (MemoryStream ms = new MemoryStream())
162 {
163 // 图片格式指定为JPG
164 image.Save(ms, ImageFormat.Jpeg);
165 // 清空缓冲区流中的所有输出
166 context.Response.ClearContent();
167 // 输出流的HTTP MIME类型设置
168 context.Response.ContentType = " image/Jpeg " ;
169 // 输出图片的二进制流
170 context.Response.BinaryWrite(ms.ToArray());
171 }
172 }
173 finally
174 {
175 g.Dispose();
176 image.Dispose();
177 }
178 }
179
180 /// <summary>
181 /// 正弦曲线Wave扭曲图片
182 /// </summary>
183 /// <param name="srcBmp"> 源图片. </param>
184 /// <param name="bxDir"> 扭曲方向 </param>
185 /// <param name="dMultValue"> 波形的幅度倍数,越大扭曲的程度越高,一般为3 </param>
186 /// <param name="dPhase"> 波形的起始相位,取值区间[0-2*PI] </param>
187 /// <returns></returns>
188 private Bitmap TwistImage(Bitmap srcBmp, bool bxDir, double dMultValue, double dPhase)
189 {
190 Bitmap destBmp = new Bitmap(srcBmp.Width, srcBmp.Height);
191
192 // 将位图背景填充为白色
193 Graphics graph = Graphics.FromImage(destBmp);
194 graph.FillRectangle( new SolidBrush(Color.White), 0 , 0 , destBmp.Width, destBmp.Height);
195 graph.Dispose();
196
197 double dBaseAxisLen = bxDir ? ( double )destBmp.Height : ( double )destBmp.Width;
198
199 for ( int i = 0 ; i < destBmp.Width; i ++ )
200 {
201 for ( int j = 0 ; j < destBmp.Height; j ++ )
202 {
203 double dx = 0 ;
204 dx = bxDir ? (PI2 * ( double )j) / dBaseAxisLen : (PI2 * ( double )i) / dBaseAxisLen;
205 dx += dPhase;
206 double dy = Math.Sin(dx);
207
208 // 取得当前点的颜色
209 int nOldX = 0 , nOldY = 0 ;
210 nOldX = bxDir ? i + ( int )(dy * dMultValue) : i;
211 nOldY = bxDir ? j : j + ( int )(dy * dMultValue);
212
213 Color color = srcBmp.GetPixel(i, j);
214 if (nOldX >= 0 && nOldX < destBmp.Width && nOldY >= 0 && nOldY < destBmp.Height)
215 {
216 destBmp.SetPixel(nOldX, nOldY, color);
217 }
218 }
219 }
220 return destBmp;
221 }
222
223 /// <summary>
224 /// 随机颜色
225 /// </summary>
226 /// <returns></returns>
227 private Color RandomColor()
228 {
229 Random randomNumFirst = new Random(DateTime.Now.Millisecond);
230 Random randomNumSencond = new Random(DateTime.Now.Millisecond);
231
232 int red = randomNumFirst.Next( 256 );
233 int green = randomNumSencond.Next( 256 );
234 int blue = (red + green > 400 ) ? 0 : 400 - red - green;
235 blue = blue > 255 ? 255 : blue;
236 return Color.FromArgb(red, green, blue);
237 }
238 }
使用时.可以直接添加一个IHttpHandler子类.
VerifyCode code = new VerifyCode( 5 );
code.CreateImage(context);
context.Session.Add( " VerifyCode " , code.GenerateCode);
此外.VerifyCode类还提供了其他的属性.可在初始化时利用3.0的特性初始化,也可以在初始化后进行赋值.
最后在WebConfig配置相关Handler配置.成果如下