当初学习一般处理程序的时候,写过一个验证码,不过是后台程序向前台输出了一张图片,图片上是几个随机写上去的字符。虽然也惊讶于许多网站上那些“扭曲”的验证码,却琢磨不透人家是怎么实现的,后来逐渐把这事遗忘了。今天在网上碰巧看到有人用php实现的案例,忍不住想着用C#来一把。当然,在此先感谢网上那位仁兄提供的思路,在下只是比着葫芦画瓢。
这里所说的“扭曲”的验证码,只是字符扭曲。由于时间仓促,我也没给顾得上添加图片噪点。先说思路:创建图片A做为背景,其次创建图片B,在图片B画上验证码文字,然后将图片B拆分成若干部分画到图片A上。打个比方,好比是把一张画纵向平均裁成若干份,然后再上下交错着粘到另一张白纸上。如果随意的上下交错排列,看到的八成就是一片乱七八糟的玩意儿,这里不妨按照一个曲线变化的规律来排列,我选择的是正弦曲线。
步骤:
1、新建一般处理程序TestCodeHandler.ashx,先定义一个随机生成验证码文字的方法,如下:
/// <summary> /// 随机生成验证码 /// </summary> /// <returns></returns> public string GetTestCode() { Random r = new Random(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < 5; i++) { int n = r.Next(65, 91); sb.Append((char)n); } return sb.ToString(); }
2、在ProcessRequest方法中,确定输出文件的类型。
context.Response.ContentType = "image/jpeg";
3、引用命名空间System.Drawing和using System.Drawing.Imaging,生成验证码图片。
using (Image img = new Bitmap(85, 40))//背景图片 { using (Image fontImg = new Bitmap(84, 38))//预先画验证码的临时图片 { //先将验证码画到临时图片fontImg上 using (Graphics fontGraphic = Graphics.FromImage(fontImg)) { fontGraphic.Clear(Color.White);//将画布涂白 //画验证吗 fontGraphic.DrawString(GetTestCode(), new Font("宋体", 18, FontStyle.Italic | FontStyle.Bold), Brushes.Black, new PointF(4, 4)); } //将临时验证码图片fontImg分成若干份画到背景图片img上 using (Graphics g = Graphics.FromImage(img)) { g.Clear(Color.White);//将画布涂白 int sum = 60;//分成60份 int niu = 6;//上下最多偏移10像素 float x = 0, y = 1;//从临时图片fontImg选取矩形区域的起始坐标 //从临时图片fontImg选取矩形区域的宽度,由于有背景图片映衬,这里只确定宽度 float width = ((float)fontImg.Width) / sum; //依次把临时图片fontImg各部分画到背景图片上 for (int i = 0; i < sum; i++) { //获取当前部分的正弦值,计算上下偏移量。但这样会使验证码的扭曲单一 float rate = (float)Math.Sin(360 * 1.0 / sum * i / 180 * Math.PI) * niu; //如果使用随机数,会有不同的变化 //Random r = new Random(DateTime.Now.Millisecond); //float rate = (float)Math.Sin(360 * 1.0 / sum * i / 180 * Math.PI) * r.Next(1,niu); //把临时图片fontImg当前部分画到背景图片上 g.DrawImage(fontImg, new Rectangle(x==0?1:(int)x, (int)y, img.Width, img.Height - 2), x, y * rate, width, fontImg.Height, GraphicsUnit.Pixel); //依次改变横坐标的下一个位置 x += width; } //为背景图片画边框 g.DrawRectangle(new Pen(Brushes.Black), new Rectangle(0, 0, img.Width - 1, img.Height - 1)); } } //将背景图片保存到输出流 img.Save(context.Response.OutputStream, ImageFormat.Jpeg);
4、测试。新建html页面,添加<img>标签,令src属性指向TestCodeHandler.ashx,并为它的onclick事件注册方法,实现点击切换图片的效果。如下:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script type="text/javascript"> function change() { document.getElementById("img").src = "TestCodeHandler.ashx?id=" + new Date().getTime(); } </script> </head> <body> <img id="img" src="TestCodeHandler.ashx" onclick="change()"/> </body> </html>
5、效果如下:
恕在下能力一般,水平有限,也只能实现上面的效果。若有高人看到此文,发现有不到之处,还望不吝赐教。
原文:http://www.cnblogs.com/wcfl/p/3795478.html