平时做项目中,可能会用到验证码,下面介绍生成码的两种的方式。
一、生成数字验证码图片
创建工具类 ( CheckUtils.java )
package com.easypan.utils;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
//生成验证码,并将验证码存入session中,以ip为key
public class CheckCodeUtils {
public static BufferedImage getCheckCode(HttpServletRequest request, String ip){
int width = 60 , height = 30;
//创建一个图像,宽60 高30
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
Random random = new Random();
g.setColor(getRandomColor(200,250));
g.fillRect(0,0,width,height);
g.setFont(new Font("Times New Roman", Font.PLAIN,18));
g.setColor(getRandomColor(160,200));
//干扰线生成
for (int i = 0; i < 10; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x,y,x+xl,y+yl);
}
String strCode = "";
for (int i = 0; i < 4; i++) {
String strNumber = String.valueOf(random.nextInt(10));
strCode = strCode+strNumber;
//设置字体颜色
g.drawString(strNumber,13*i+6,20);
}
System.out.println("当前ip"+ip);
System.out.println("当前验证码"+strCode);
request.getSession().setAttribute(ip,strCode);
g.dispose();
return image;
}
/**
* 随机获取颜色的方法
* @return
*/
public static Color getRandomColor (int fc , int bc){
Random random = new Random();
Color reandomColor = null;
if(fc > 255){
fc = 255;
}
if(bc > 255){
bc = 255;
}
int r =fc + random.nextInt(bc-fc);
int g = fc + random.nextInt(bc-fc);
int b = fc + random.nextInt(bc-fc);
reandomColor = new Color(r,g,b);
return reandomColor;
}
}
使用
@GetMapping("/checkCode")
@ApiOperation(value="获取验证码 - 数字",produces = "application/octet-stream")
public void getCheckCode(HttpServletResponse response, HttpServletRequest request) throws IOException {
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","No-cache");
response.setDateHeader("Expires",0);
response.setContentType("image/jpeg");
String ip = request.getRemoteAddr();
BufferedImage image = CheckCodeUtils.getCheckCode(request, ip);
ImageIO.write(image,"jpeg",response.getOutputStream());
response.getOutputStream().flush();
response.getOutputStream().close();
}
效果图
二、生成 数字+字母 验证码图片
创建工具类 ( CreateImageCode.java )
package com.easypan.utils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.util.Locale;
import java.util.Random;
public class CreateImageCode {
//图片的宽度
private int width = 160;
//图片的高度
private int height = 40;
//验证码字符个数
private int codeCount=4;
//验证码干扰线数
private int lineCount=20;
//验证码
private String code=null;
//验证码图片buffer
private BufferedImage buffImg=null;
//创建一个生成随机数对象
Random random = new Random();
//构造函数
public CreateImageCode(){
creatImage();
}
public CreateImageCode(int width,int height){
this.width = width;
this.height = height;
creatImage();
}
public CreateImageCode(int width,int height,int codeCount){
this.width = width;
this.height = height;
this.codeCount = codeCount;
creatImage();
}
public CreateImageCode(int width,int height,int codeCount,int lineCount){
this.width = width;
this.height = height;
this.codeCount = codeCount;
this.lineCount = lineCount;
creatImage();
}
//生成图片
private void creatImage(){
//字体的宽度
int fontWidth = width / codeCount;
//字体的高度
int fontHeight = height - 5;
int codeY = height - 8;
//图像buff
buffImg = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics g = buffImg.getGraphics();
//设置背景色
g.setColor(getRandColor(200,250));
g.fillRect(0,0,width,height);
//设置字体
Font font = new Font("Fixedsys", Font.BOLD, fontHeight);
g.setFont(font);
//设置干扰线
for(int i=0;i<lineCount;i++){
int xs = random.nextInt(width);
int ys = random.nextInt(height);
int xe = xs + random.nextInt(width);
int ye = ys + random.nextInt(height);
g.setColor(getRandColor(1,255));
g.drawLine(xs,ys,xe,ye);
}
//添加噪点
float yawpRate = 0.01f;//噪声率
int area =(int) (yawpRate * width * height);
for (int i=0;i<area;i++){
int x = random.nextInt(width);
int y = random.nextInt(height);
buffImg.setRGB(x,y,random.nextInt(255));
}
String str1 = randomStr(codeCount);//得到随机字符
this.code = str1;
for (int i=0;i<codeCount;i++){
String strRand = str1.substring(i,i+1);
g.setColor(getRandColor(1,255));
//g.drawString(str,x,y) ---- str:为要画出来的东西;x 和 y :表示要画的东西最左则字符的基线位于此图形上下文坐标系的 (x,y)位置处
g.drawString(strRand,i * fontWidth + 3,codeY);
}
}
//得到随机字符
private String randomStr(int n){
String str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567990";
String str2 = "";
int len = str1.length() - 1;
double r;
for (int i=0;i<n;i++){
r = (Math.random()) * len;
str2 = str2 + str1.charAt((int) r);
}
return str2;
}
//得到随机颜色
private Color getRandColor(int fc,int bc){
if (fc>255) fc = 255;
if (bc>255) bc = 255;
int r = fc + random.nextInt(bc-fc);
int g = fc + random.nextInt(bc-fc);
int b = fc + random.nextInt(bc-fc);
return new Color(r,g,b);
}
//产生随机字体
private Font getFont(int size){
Random random = new Random();
Font font[] = new Font[5];
font[0] = new Font("Ravie",Font.PLAIN,size);
font[1] = new Font("Antique Olive Compact",Font.PLAIN,size);
font[2] = new Font("Fixedsys",Font.PLAIN,size);
font[3] = new Font("Wide Latin",Font.PLAIN,size);
font[4] = new Font("Gill Sans Ultra Bold",Font.PLAIN,size);
return font[random.nextInt(5)];
}
//扭曲方法
private void shear(Graphics g,int wl,int hl,Color color){
shearX(g,wl,hl,color);
shearY(g,wl,hl,color);
}
private void shearX(Graphics g, int wl, int hl, Color color) {
int period = random.nextInt(2);
boolean borderGap = true;
int frames = 1;
int phase = random.nextInt(2);
for (int i = 0; i < hl; i++) {
double d = (double) (period >> 1)
* Math.sin((double) i / (double) period
+ (6.2831853071795862D * (double) phase)
/ (double) frames);
g.copyArea(0, i, wl, 1, (int) d, 0);
if (borderGap) {
g.setColor(color);
g.drawLine((int) d, i, 0, i);
g.drawLine((int) d + wl, i, wl, i);
}
}
}
private void shearY(Graphics g, int w1, int h1, Color color) {
int period = random.nextInt(40) + 10; // 50;
boolean borderGap = true;
int frames = 20;
int phase = 7;
for (int i = 0; i < w1; i++) {
double d = (double) (period >> 1)
* Math.sin((double) i / (double) period
+ (6.2831853071795862D * (double) phase)
/ (double) frames);
g.copyArea(i, 0, 1, h1, 0, (int) d);
if (borderGap) {
g.setColor(color);
g.drawLine(i, (int) d, i, 0);
g.drawLine(i, (int) d + h1, i, h1);
}
}
}
public void write(OutputStream os){
try {
ImageIO.write(buffImg,"png",os);
os.close();
}catch (Exception e){
e.printStackTrace();
}
}
public String getCode(){
return code.toLowerCase();
}
}
使用
@GetMapping("/getCode")
@ApiOperation(value="获取验证码 - 字母+数字",produces = "application/octet-stream")
public void getCode(HttpServletResponse response, HttpSession session,Integer type) throws IOException {
CreateImageCode imageCode = new CreateImageCode(130,38,5,10);
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","No-cache");
response.setDateHeader("Expires",0);
response.setContentType("image/jpeg");
String code = imageCode.getCode();
imageCode.write(response.getOutputStream());
}
效果图