
正文
java图片验证码源代码 java绘制验证码
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
怎样用java实现验证码
package com.servlet;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.imageio.ImageIO;
public class PictureCheckCode extends HttpServlet {
private static final long serialVersionUID = 1L;
public PictureCheckCode() {
super();
}
public void destroy() {
super.destroy();
}
public void init() throws ServletException {
super.init();
}
/*该方法主要作用是获得随机生成的颜色*/
public Color getRandColor(int s,int e){
Random random=new Random ();
if(s255) s=255;
if(e255) e=255;
int r,g,b;
r=s+random.nextInt(e-s); //随机生成RGB颜色中的r值
g=s+random.nextInt(e-s); //随机生成RGB颜色中的g值
b=s+random.nextInt(e-s); //随机生成RGB颜色中的b值
return new Color(r,g,b);
}
@Override
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//设置不缓存图片
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "No-cache");
response.setDateHeader("Expires", 0);
//指定生成的响应图片,一定不能缺少这句话,否则错误.
response.setContentType("image/jpeg");
int width=86,height=22; //指定生成验证码的宽度和高度
BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); //创建BufferedImage对象,其作用相当于一图片
Graphics g=image.getGraphics(); //创建Graphics对象,其作用相当于画笔
Graphics2D g2d=(Graphics2D)g; //创建Grapchics2D对象
Random random=new Random();
Font mfont=new Font("楷体",Font.BOLD,16); //定义字体样式
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height); //绘制背景
g.setFont(mfont); //设置字体
g.setColor(getRandColor(180,200));
//绘制100条颜色和位置全部为随机产生的线条,该线条为2f
for(int i=0;i100;i++){
int x=random.nextInt(width-1);
int y=random.nextInt(height-1);
int x1=random.nextInt(6)+1;
int y1=random.nextInt(12)+1;
BasicStroke bs=new BasicStroke(2f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL); //定制线条样式
Line2D line=new Line2D.Double(x,y,x+x1,y+y1);
g2d.setStroke(bs);
g2d.draw(line); //绘制直线
}
//输出由英文,数字,和中文随机组成的验证文字,具体的组合方式根据生成随机数确定。
String sRand="";
String ctmp="";
int itmp=0;
//制定输出的验证码为四位
for(int i=0;i4;i++){
switch(random.nextInt(3)){
case 1: //生成A-Z的字母
itmp=random.nextInt(26)+65;
ctmp=String.valueOf((char)itmp);
break;
case 2: //生成汉字
String[] rBase={"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
//生成第一位区码
int r1=random.nextInt(3)+11;
String str_r1=rBase[r1];
//生成第二位区码
int r2;
if(r1==13){
r2=random.nextInt(7);
}else{
r2=random.nextInt(16);
}
String str_r2=rBase[r2];
//生成第一位位码
int r3=random.nextInt(6)+10;
String str_r3=rBase[r3];
//生成第二位位码
int r4;
if(r3==10){
r4=random.nextInt(15)+1;
}else if(r3==15){
r4=random.nextInt(15);
}else{
r4=random.nextInt(16);
}
String str_r4=rBase[r4];
//将生成的机内码转换为汉字
byte[] bytes=new byte[2];
//将生成的区码保存到字节数组的第一个元素中
String str_12=str_r1+str_r2;
int tempLow=Integer.parseInt(str_12, 16);
bytes[0]=(byte) tempLow;
//将生成的位码保存到字节数组的第二个元素中
String str_34=str_r3+str_r4;
int tempHigh=Integer.parseInt(str_34, 16);
bytes[1]=(byte)tempHigh;
ctmp=new String(bytes);
break;
default:
itmp=random.nextInt(10)+48;
ctmp=String.valueOf((char)itmp);
break;
}
sRand+=ctmp;
Color color=new Color(20+random.nextInt(110),20+random.nextInt(110),random.nextInt(110));
g.setColor(color);
//将生成的随机数进行随机缩放并旋转制定角度 PS.建议不要对文字进行缩放与旋转,因为这样图片可能不正常显示
/*将文字旋转制定角度*/
Graphics2D g2d_word=(Graphics2D)g;
AffineTransform trans=new AffineTransform();
trans.rotate((45)*3.14/180,15*i+8,7);
/*缩放文字*/
float scaleSize=random.nextFloat()+0.8f;
if(scaleSize1f) scaleSize=1f;
trans.scale(scaleSize, scaleSize);
g2d_word.setTransform(trans);
g.drawString(ctmp, 15*i+18, 14);
}
HttpSession session=request.getSession(true);
session.setAttribute("randCheckCode", sRand);
g.dispose(); //释放g所占用的系统资源
ImageIO.write(image,"JPEG",response.getOutputStream()); //输出图片
}
}
相关问答
Q1: 用Java做一个验证码识别的程序,要识别的验证码:http://group.bj.chinamobile.com/edsmp/ValidateNum
验证码识别,费力效果差,除非非常简单的图片,否则极难识别,而且验证码图片的代码,人家只需要稍微弄复杂点,识别的复杂度直线上升,成功率直线下降。像hotmail, google, yahoo那种就直接放弃,
不过像这种简单的,你可以试试,用模式匹配:
例如单个数字大小是16 * 16像素, 那就划分成16*16块,每个块1个像素,编号,特征就是a[0][0] - 白, a[0][1] - 白, a[0][2]黑……这种,存下来,把要识别的图片上的数字,也这样处理,然后跟保存下来的特征码进行匹配就行了,看看有多少是一样的,超过50%就可以认为找到了,或者把阈值设更低点
难点在于要识别的图片上面有干扰点,要排除,以你给出的图片来说,可以这样:
1. 先统一黑白:如果一个像素跟白色很接近,就认为是白色,否则认为是黑色。(如果底色是随机的,那就把区域色块最大的认为是白色,其他的黑色)
2. 每个像素周围有8个像素,计算出这个区域内的平均灰度,例如这9个点中超过4个是黑色,那就认为这个像素是黑色
Q2: 怎么样通过java代码得到页面上的验证码
具体的倒没做过,不过原理应该差不多,不过不会简单,一句两句是将不清楚的,呵呵
基本原理是这样的,这个图片在IE的缓存文件夹Local Settings\Temporary Internet Files中一定会有一个对应的固定名称的图片,每次这个图片文件名称是一样的,只是里面的内容不一样,你可以找一下看看,呵呵,下面就简单了吧,不过,前提是这个页面你要在浏览器加载过,这样才能形成缓存文件。
你点这些分,我就说这么多了~
===================================================
呵呵,你这个不好解决,是不是想搞自动注册呢?
人家验证码明显是不会在客户端产生的,这个是保存在服务端的,那你如何得到呢?客户端得到的只是一个图片而已,方法也有,就是你把这个图片得到,动态解析,从这个图片的解析中获取它所表示的内容,这个难度有点大的,图片解析难度比较高的,如果再加一些干扰,呵呵,基本能解出来的不是高手也差不多了。
所以,你的这个问题本身比较难实现,验证码使用的目的就是为了防止自动注册,而且这个注册码本身是不会传递到客户端的,所以,你要获取的可能性很小。
java图片验证码源代码的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java绘制验证码、java图片验证码源代码的信息别忘了在本站进行查找喔。








