一、实现工具
语言:java
编辑器:IntelliJ IDEA 2019.3.3 x64
二、实现功能
随机生成一组字符串 String randomString(int count)
对图片进行噪点处理 void randompoint(BufferedImage img, Random rd)
对图片进行划线处理 void line(Graphics g, Random rd)
复制像素使图片信息模糊 void shear(Graphics g)
校验码信息的传递 req.getSession().setAttribute("code",code);
三、实现代码
/**
package org.example.project2.controller;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet("/captcha")
public class CaptcheController extends HttpServlet {
private final int Width=100;
private final int Height=80;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
BufferedImage img =new BufferedImage(Width,Height,BufferedImage.TYPE_INT_RGB);
Graphics g=img.getGraphics();
Random rd=new Random();
g.fillRect(0,0,Width,Height);
g.setFont(new Font("宋体",Font.BOLD,35));
g.setColor(Color.black);
String code=randomString(4);
req.getSession().setAttribute("code",code);
g.drawString(code,10,55);
line(g,rd);
shear(g);
g.dispose();
randompoint(img,rd);
ServletOutputStream out =resp.getOutputStream();
ImageIO.write(img,"JPEG",out);
try{
out.flush();
}catch (Exception ex){}
finally {
out.close();
}
}
/**
* 通过制造噪点,使图片的信息变得混乱,让验证码不易被机器识别。
* @param img 生成的图片
* @param rd 随机生成的数值
*/
private void randompoint(BufferedImage img, Random rd) {
float zd = 0.05f;
int area = (int) (zd * Width * Height);
for (int i = 0; i < area; i++) {
int x = rd.nextInt(Width);
int y = rd.nextInt(Height);
img.setRGB(x, y, 0);
}
}
/**
*通过划线将图片的信息进行部分掩盖,让验证码不易被机器识别。
* @param g 绘制的图片
* @param rd 随机生成的数字
*/
private void line(Graphics g, Random rd){
g.setColor(Color.red); //此处的setcolor是在drawString完成后实行,所以设置的是为线条的颜色。
for (int i = 0; i < 20; i++) {
int x = rd.nextInt(Width - 1);
int y = rd.nextInt(Height - 1);
int xl = rd.nextInt(6) + 1;
int yl = rd.nextInt(12) + 1;
g.drawLine(x, y, x+xl+40, y+yl+20);
}
}
/**
*通过复制像素,使图片变得模糊,让验证码不易被机器识别。
* @param g 绘制的图片
*/
private void shear(Graphics g) {
Random r=new Random(1);
for (int i = 0; i < Width; i++) {
g.copyArea(0, i, Height, 1, r.nextInt(5), 0);
}
}
/**
* 随机生成一组字符串
* @param count:生成的字符串中的字符个数
* @return 生成的随机字符串信息
*/
public String randomString(int count){
StringBuilder builder=new StringBuilder();
String source="abcdefghijklmnpqrstuvwxy0123456789";
Random rd=new Random();
for (int i=0;i
int pos = rd.nextInt(source.length());
String s = source.substring(pos, pos + 1);
builder.append(s);
}
return builder.toString();
}
}
复制代码
四、结果截图
五、部分可修改的值介绍
更改randomString(int count)下的source字符串取值进行校验码取值范围修改。
更改shear(Graphics g)下的 r.nextInt(5)进行复制像素修改,数值越大,图片越散碎反之数值越小越整齐。