//**********获取验证码图片*********************************************************//
function getcodeimg()
{
var num = Math.ceil(Math.random()*100)
document.getElementById("codeimg").src = "VerifyCode.aspx?Num="+num
}
这里codeimg是网页上验证码图片的id。如下:
<img id="codeimg" alt="看不清楚请点击图片!" src="VerifyCode.aspx" onclick="getcodeimg()"/>
//*********************************************************************************//
建立一个单独生成验证码aspx页面,后台代码如下:
using System
using System.Collections
using System.ComponentModel
using System.Data
using System.Web
using System.Web.SessionState
using System.Web.UI
using System.Web.UI.WebControls
using System.Web.UI.HtmlControls
using System.Drawing
using System.Drawing.Imaging
using System.Drawing.Text
/// <summary>
/// 页面验证码程序
/// 使用:在页面中加入HTML代码 <img src="VerifyCode.aspx">
/// </summary>
public partial class VerifyCode : System.Web.UI.Page
{
static string[] FontItems = new string[] { "Arial",
"Helvetica",
"Geneva",
"sans-serif",
"Verdana"
}
static Brush[] BrushItems = new Brush[] { Brushes.OliveDrab,
Brushes.ForestGreen,
Brushes.DarkCyan,
Brushes.LightSlateGray,
Brushes.RoyalBlue,
Brushes.SlateBlue,
Brushes.DarkViolet,
Brushes.MediumVioletRed,
Brushes.IndianRed,
Brushes.Firebrick,
Brushes.Chocolate,
Brushes.Peru,
Brushes.Goldenrod
}
static string[] BrushName = new string[] {"OliveDrab",
"ForestGreen",
"DarkCyan",
"LightSlateGray",
"RoyalBlue",
"SlateBlue",
"DarkViolet",
"MediumVioletRed",
"IndianRed",
"Firebrick",
"Chocolate",
"Peru",
"Goldenrod"
}
private static Color BackColor= Color.White
private static Pen BorderColor = Pens.DarkGray
private static int Width= 58
private static int Height = 25
private Random _random
private string _code
private int_brushNameIndex
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
//InitializeComponent()
//base.OnInit(e)
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//this.Load += new System.EventHandler(this.Page_Load)
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void Page_Load(object sender, System.EventArgs e)
{
if (!IsPostBack)
{
//
// TODO : initialize
//
this._random = new Random()
this._code = GetRandomCode()
//
// TODO : use Session["code"] save the VerifyCode
//
Session["code"] = this._code
//
// TODO : output Image
//
this.SetPageNoCache()
this.OnPaint()
}
}
/// <summary>
/// 设置页面不被缓存
/// </summary>
private void SetPageNoCache()
{
Response.Buffer = true
Response.ExpiresAbsolute = System.DateTime.Now.AddSeconds(-1)
Response.Expires = 0
Response.CacheControl = "no-cache"
Response.AppendHeader("Pragma","No-Cache")
}
/// <summary>
/// 取得一个 4 位的随机码
/// </summary>
/// <returns></returns>
private string GetRandomCode()
{
return Guid.NewGuid().ToString().Substring(0, 4)
}
/// <summary>
/// 随机取一个字体
/// </summary>
/// <returns></returns>
private Font GetFont()
{
int fontIndex = _random.Next(0, FontItems.Length)
FontStyle fontStyle = GetFontStyle(_random.Next(0, 2))
return new Font(FontItems[fontIndex], 12, fontStyle)
}
/// <summary>
/// 取一个字体的样式
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
private FontStyle GetFontStyle(int index)
{
switch (index)
{
case 0:
return FontStyle.Bold
case 1:
return FontStyle.Italic
default:
return FontStyle.Regular
}
}
/// <summary>
/// 随机取一个笔刷
/// </summary>
/// <returns></returns>
private Brush GetBrush()
{
int brushIndex = _random.Next(0, BrushItems.Length)
_brushNameIndex = brushIndex
return BrushItems[brushIndex]
}
/// <summary>
/// 绘画事件
/// </summary>
private void OnPaint()
{
Bitmap objBitmap = null
Graphics g = null
try
{
objBitmap = new Bitmap(Width, Height)
g = Graphics.FromImage(objBitmap)
Paint_Background(g)
Paint_Text(g)
Paint_TextStain(objBitmap)
Paint_Border(g)
objBitmap.Save(Response.OutputStream, ImageFormat.Gif)
Response.ContentType = "image/gif"
}
catch{}
finally
{
if (null != objBitmap)
objBitmap.Dispose()
if (null != g)
g.Dispose()
}
}
/// <summary>
/// 绘画背景颜色
/// </summary>
/// <param name="g"></param>
private void Paint_Background(Graphics g)
{
g.Clear(BackColor)
}
/// <summary>
/// 绘画边框
/// </summary>
/// <param name="g"></param>
private void Paint_Border(Graphics g)
{
g.DrawRectangle(BorderColor, 0, 0, Width - 1, Height - 1)
}
/// <summary>
/// 绘画文字
/// </summary>
/// <param name="g"></param>
private void Paint_Text(Graphics g)
{
g.DrawString(_code, GetFont(), GetBrush(), 3, 1)
}
/// <summary>
/// 绘画文字噪音点
/// </summary>
/// <param name="g"></param>
private void Paint_TextStain(Bitmap b)
{
for (int n=0n<30n++)
{
int x = _random.Next(Width)
int y = _random.Next(Height)
b.SetPixel(x, y, Color.FromName(BrushName[_brushNameIndex]))
}
}
}
node-ccap模块生成captcha验证码
用node做web开发很多都可能碰到需要验证码的地方,之前在github上搜索,有一些比如node-captcha等的类库,都需要依赖第三方的图形处理库或者软件,像我之前安装cario这个图形库时,真是费了好大一番劲,但是其实我们只用到了这些图形库的一点点小功能,比如图片的尺寸修改裁剪,或者生产验证码。
先介绍一下CImg这个c++的图形库吧,CImg是一个跨平台的C++的图像处理库,提供了加载、处理、显示、保存等一系列功能,最吸引人的地方是整个图形库就一个CImg.h这个文件,所以非常的便携绿色环保,带到哪里都可以进行编译使用,不用安装一大推依赖。于是我就想利用这个CImg图形库做一个简单的demo,就从实现验证码这个功能入手,当然可以完全利用这个库来做裁剪图片等其他功能。
ccap模块是基于CImg图形库的封装,让它可以供node使用,由于CImg图形库的便携性,所以ccap模块可以完全不依赖其他任何第三方图形库或者软件而独立工作,也就说如果只是想要生成简单的验证码,只要require这个ccap模块即可。
生成的图片示例:
1、安装:
通用方法:npm install ccap
或者通过github下载,地址:https://github.com/DoubleSpout/ccap
2、性能:
在2cpu的linux 64位服务器上生成验证码速度可以达到1200次/秒,测试生成的图片是BMP的,jpeg的图片验证码生成速度大约在600次/秒。
3、声明方法:
var ccap = require('ccap')var captcha1 = ccap()
var captcha2 = ccap(width, height, offset)
var captcha3 = ccap({
width:256,//set width,default is 256
height:60,//set height,default is 60
offset:40,//set text spacing,default is 40
quality:100,//set pic quality,default is 50
generate:function(){//Custom the function to generate captcha text
//generate captcha text here
return text//return the captcha text
}
})
可以通过上述代码实例化一个ccap类。
1、不传任何参数,全部使用默认的参数进行生成验证码
2、只传递宽,高,偏移进行实例化,调整图片的大小,和图片中文字的间隔
3、传递一个对象,除了宽,高和偏移,还传递了图片质量以及生成随机数的方法,ccap模块会根据自定义函数return的字符串作为图片验证码的内容,默认是0-9,A-Z的6位随即字符串。
理论上可以生产很多不同的ccap的实例,而且他们之间互相没有影响,所以即使是通过cluster开启多进程的node同时生产验证码也不存在互相锁止的影响。
对于图片质量只对jpeg图片有效,如果没有安装任何jpeg的lib库的话,只能使用bmp未压缩图形了,体积比较大,但是生成速度比较快。
4、使用方法,get():
var ccap = require('ccap')
var captcha = ccap()
var ary = captcha.get()//ary[0] is captcha's text,ary[1] is captcha picture buffer.
var text = ary[0]
var buffer = ary[1]
实例化ccap类之后,会得到captcha对象,这个对象只有一个对外方法,get(),这个方法每次调用都会返回验证码buffer和对应的text字符串内容,保存在数组里,类似这样的结构:
["captcha text","picture buffer"]
5、一个简单的web例子:
var http = require('http')var ccap = require('ccap')()//Instantiated ccap class
http.createServer(function (request, response) {
if(request.url == '/favicon.ico')return response.end('')//Intercept request favicon.ico
var ary = ccap.get()
var txt = ary[0]
var buf = ary[1]
response.end(buf)
console.log(txt)
}).listen(8124)
console.log('Server running at
http://127.0.0.1:8124/'
)
上面这个例子会将验证码返回给客户端,并且把对应的验证码的文字输出出来,同时拦截了favicon.ico的请求。
结果如下图:
有兴趣的TX可以下载下来试试,如果安装有jpeg库的话,可以把根目录下的binding.jpeg.gyp覆盖改名为binding.gyp然后rebuild就可以使用jpeg图片作为验证码了,体积会小很多。另外ccap模块做了一些缓存的机制,尽量发挥更好的性能。
目前ccap已经对linux系统支持jpeg验证码,体积从45kb直降到6kb