Asp.net波形随机验证码
2010-08-11 13:27 空逸云 阅读(515) 评论(4) 编辑 收藏 举报网上有许多关于验证码生成的类.鉴于以后方便.自写了一个波形验证码,其中波形操作参考了.无刷新仿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配置.成果如下
作者:空逸云
出处:http://kongyiyun.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://kongyiyun.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
您的支持是我前进的动力,请猛击.: