1.新建一个javaweb项目
2.新建一个action包,用来写servlet
3.在action包里新建一个Servlet类名为CaptchaAction,仅重写service方法。
准备工作做完后,下面开始写代码:
response.setContentType("image/jpeg"); //告诉浏览器发送的是图片
BufferedImage image=new BufferedImage(130,30,BufferedImage.TYPE_INT_RGB); //在缓存区创建一个图片,三个参数分别是图片的宽,高和颜色取值类型
Graphics2D g=(Graphics2D)image.getGraphics(); //拿到一个画家,其中Graphics2D是Graphics的子类,功能比Graphics要强,因此强转一下
g.setColor(Color.WHITE); //设置填充颜色为白色
g.fillRect(0,0,image.width(),image.height()); //画一个填充矩形,四个参数的含义是起始点x坐标,y坐标,终止点x坐标,y坐标
g.setColor(Color.BLACK); //设置颜色为黑色
g.drawRect(0, 0, image.getWidth()-1, image.getHeight()-1) //绘制一个矩形为边框,四个参数含义同填充矩形
String sn=randomString(4); //随机一个字符串,这个方法是自定义方法,方法体在后边
//绘制验证码
g.setFont(new Font("微软雅黑",Font.BLOD,20)); //设置字体,参数为Font类型,new一个Font,三个参数分别是字体,样式(加粗或倾斜),字体大小
for(int i=0;i<sn.length;i++){ //循环在图片上画取出的字符
g.setColor(randomColor()); //每次画之前随机一个颜色,randoColor()是自定义随机颜色的方法,方法体在后边
int deg=randomDeg();
double d=Math.PI*deg/180; //获取一个随机度数,转为弧度制
g.rotate(d,15+30*i,15); //每次都以当前字符中心为坐标原点,随机旋转一个度数
g.drawString(sn.charAt(i)+"",13+30*i,25); //画出当前字符,每次画字符的位置不能重复
g.rotate(d*-1,15+30*i,15); //画完当前字符之后要把画布旋转回来
}
for(int i=0;i<10;i++0{ //随机十条干扰线
Random random=new Random();
g.setColor(randomColor);
int x1=random.nextInt(image.getWidth());
int y1=random.nextInt(image.getHeight());
int x2=random.nextInt(20)-10+x1;
int y2=random.nextInt(20)-10+y1;
g.drawLine(x1, y1, x2, y2); //画线,四个参数是起始点x坐标,y坐标,终点x坐标,y坐标
}
for(int i=0;i<50;i++) { //随机50个干扰点
Random random=new Random();
g.setColor(randomColor());
int x1=random.nextInt(image.getWidth());
int y1=random.nextInt(image.getHeight());
int x2=x1;
int y2=y1;
g.drawLine(x1, y1, x2, y2); //画点,当线的起始点和终点是同一个点时,是一个点
}
ImageIO.write(image, "jpeg", response.getOutputStream()); //将画好的图片发给浏览器
service方法体书写完毕。
附service方法中用到的一些自定义方法:
//随机字符串方法
private String randomString(int length){ //传一个int,定义取出字符的数量
Random random=new Random(); //new一个随机函数
String str="1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM"; //定义一个字符串
String sn=""; //定义一个空字符串用来保存随机结果
for(int i=0;i<length;i++){
int index=random.nextInt(str.length); //随机一个下标,数字大小不超过str字符串长度
sn+=str.charAt(index); //通过下标取得相应字符,保存在sn中
}
return sn; //返回sn
}
//获取随机颜色方法
private Color randomColor(){
Random random=new Random();
Color color=new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)); //new一个color,参数为三个,RGB颜色命名法,随机数大小不超过255
return color;
}
//获取随机度数方法
private int randomDeg() {
int [] arr= {1,-1}; //定义一个新数组,仅有1,-1两个数,用来调整度数的正负值,让随机出来的验证码左右都能倾斜
Random random=new Random();
return (15+random.nextInt(25))*arr[random.nextInt(2)];
}