Java web基于BufferedImage实现动态图片验证码
保姆级注释,一个文件复制粘贴就能使用
效果
VerificationCodeService.java文件
package com.laner.service;
import org.springframework.stereotype.Service;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
@Service
public class VerificationCodeService {
public Map getRandomVerificationCodeImage(){
Random random = new Random();
//设置图片宽高
int width = 100;
int height = 40;
//创建图像
BufferedImage bImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//获得图像图形(graphics)
// 图形是图像的抽象,它反映图像上的关键特征,如点、线、面等。
// 图形的表示不直接描述图像的每一点,而是描述产生这些点的过程和方法。
Graphics graphics = bImage.getGraphics();
graphics.fillRect(0, 0, width, height); //将在整个图形上操作,而不是某一部分
//生成验证码
int codeLength = 4; //验证码长度
String codeFamily = "宋体"; //验证码字体
int codeSize = 18; //验证码字体大小
int codeStyle = 30; //验证码字体样式(例如:斜体、加粗等,详情可查帮助文档)
int codeWidth = width / codeLength; //一个验证码在图形中占据的宽度
char[] codeElements = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890qwertyuiopasdfghjklzxcvbnm".toCharArray(); //验证码内容
StringBuffer codeBuffer = new StringBuffer(); //拼接字节形成验证码
for (int i = 0; i < codeLength; i++) {
//获得随机字符
char ch = codeElements[random.nextInt(codeElements.length)];
//设置随机颜色
graphics.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)));
//设置字体
graphics.setFont(new Font(codeFamily,codeStyle,codeSize));
//绘制字符,每绘制一次,需往右移动响应距离,以免绘制重复位置
//x:代指绘制左边界 y:代指绘制下边界
graphics.drawString(ch + "", i * (codeWidth) + (codeWidth - codeSize) / 2, (height + codeSize) / 2);
codeBuffer.append(ch);
}
String code = codeBuffer.toString();
//生成噪点
double noiseRatio = 0.04; //噪点比率
int noiseCount = (int) (noiseRatio * width * height); //噪点个数
for (int i = 0; i < noiseCount; i++) {
//绘制噪点
bImage.setRGB(random.nextInt(width), random.nextInt(height), random.nextInt());
}
//生成直线
int lineCount = 4; //直线条数
int x_start, x_end, y_start, y_end; //直线位置
for (int i = 0; i < lineCount; i++) {
x_start = random.nextInt(width);
x_end = random.nextInt(width);
y_start = random.nextInt(height);
y_end = random.nextInt(height);
//设置随机颜色
graphics.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)));
//绘制直线
graphics.drawLine(x_start, y_start, x_end, y_end);
}
Map<String, Object> map = new HashMap<>();
map.put("verificationCodeImage", bImage);
map.put("verificationCode", code);
return map;
}
}
在controller中调用VerificationCodeService
package com.laner.controller;
import com.laner.service.VerificationCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Map;
@Controller
@RequestMapping("/register/")
public class RegisterController {
@Autowired
private VerificationCodeService vCodeService;
@RequestMapping("verificationCode")
public void registerVerificationCode(HttpSession session, HttpServletResponse response) throws IOException {
Map map = vCodeService.getRandomVerificationCodeImage();
BufferedImage vCodeImage = (BufferedImage) map.get("verificationCodeImage");
String vCode = (String) map.get("verificationCode");
session.setAttribute("vCode", vCode);
ImageIO.write(vCodeImage, "JPG", response.getOutputStream());
}
}
在前端调用
第一种 点击文字换图
html中
<img src="register/verificationCode" id="imgCodeId"/>
<a href="#" id="aCodeId">换一张</a>
js中
<script src="js/jquery-1.9.1.min.js"></script>
<script>
$(function(){
$("#aCodeId").click(function () {
var datetime = new Date().getTime();
$("#imgCodeId").attr("src","register/verificationCode?"+datetime);
});
})
</script>
第二种 点击图片换图
<img src="/register/verificationCode" height="32px" onclick="changeCheckCode(this)">
<script type="text/javascript">
//图片点击事件
function changeCheckCode(img) {
img.src="/register/verificationCode?"+new Date().getTime();
}
</script>
总结
一边学习一边记录