Asp.net波形隨機驗證碼
2010-08-11 13:27 空逸云 閱讀(544) 評論(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
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
您的支持是我前進的動力,請猛擊.:

浙公網安備 33010602011771號