java实现图片验证码

可以生成纯数字验证码,也可以生成数字+字母组合验证码,取决于使用哪个构造方法



import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.Random;

/**
 * @author shazeys
 * @description: 字符图片验证码
 * @date 2019/12/9 15:06
 */
public class PicAuthImg {

    private static final Logger LOG = LoggerFactory.getLogger(PicAuthImg.class);

    public static final String SESSION_PARAM_PICCODE = "picAuthCode";
    /** 随机产生数字与字母组合的字符串 取消0,1,l,I,O 容易混淆的值*/
    private final String randStr = "23456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
    private final String randNum = "0123456789";

    /** 图片宽 */
    private int width = 95;

    /** 图片高 */
    private int height = 25;

    /** 干扰线数量 */
    private int lineSize = 40;

    /** 随机产生字符数量 */
    private int stringNum = 4;

    /** 仅数字 */
    private boolean onlyNum = false;

    /** 需要处理的码 */
    private String code ;
    /** 验证码图片Buffer */
    private BufferedImage buffImg = null;

    private Random random = new Random();
    /** 使用默认参数 */
    public PicAuthImg() {
        this.createPicture();
    }
    public PicAuthImg(boolean onlyNum) {
        this.onlyNum = onlyNum;
        this.createPicture();
    }
    /** 指定验证码 */
    public PicAuthImg(String code) {
        this.code = code;
        this.createPictureCode();
    }
    /** 指定图片大小和验证码 */
    public PicAuthImg(int width, int height, int lineSize, String code) {
        this.width = width;
        this.height = height;
        this.lineSize = lineSize;
        this.code = code;
        this.createPictureCode();
    }

    public PicAuthImg(int stringNum) {
        this.stringNum = stringNum;
        this.createPicture();
    }

    public PicAuthImg(int stringNum, boolean onlyNum) {
        this.stringNum = stringNum;
        this.onlyNum = onlyNum;
        this.createPicture();
    }

    public PicAuthImg(int width, int height, int lineSize, int stringNum) {
        this.width = width;
        this.height = height;
        this.lineSize = lineSize;
        this.stringNum = stringNum;
        this.createPicture();
    }
    public PicAuthImg(int width, int height, int lineSize, int stringNum,boolean onlyNum) {
        this.width = width;
        this.height = height;
        this.lineSize = lineSize;
        this.stringNum = stringNum;
        this.onlyNum = onlyNum;
        this.createPicture();
    }

    public String getCode() {
        return code;
    }

    public void setOnlyNum(boolean onlyNum){
        this.onlyNum=onlyNum;
    }
    private void createPicture(){
        buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);

        //产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
        Graphics g = buffImg.getGraphics();
        //图片大小
        g.fillRect(0, 0, width, height);
        //字体大小
        g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));
        //字体颜色
        g.setColor(getRandColor(110, 133));
        // 绘制干扰线
        for (int i = 0; i <= lineSize; i++) {
            drowLine(g);
        }
        // 绘制随机字符
        String verCode = "";
        for (int i = 1; i <= stringNum; i++) {
            verCode += drowString(g, i);
        }
        LOG.info("生成验证码[{}]",verCode);
        code = verCode;
        g.dispose();
    }

    private void createPictureCode(){
        buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);

        //产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
        Graphics g = buffImg.getGraphics();
        //字体大小
        g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));
        //图片大小
        g.fillRect(0, 0, width, height);
        //字体颜色
        g.setColor(getRandColor(110, 133));
        // 绘制干扰线
        for (int i = 0; i <= lineSize; i++) {
            drowLine(g);
        }
        // 绘制随机字符
        for (int i = 0; i < code.length(); i++) {
            drowString(g, i+1,String.valueOf(code.charAt(i)));
        }
        LOG.info(code);
        g.dispose();
    }

    public void write(HttpServletResponse response){
        try {
            // 将内存中的图片通过流动形式输出到客户端
            ImageIO.write(buffImg, "JPEG", response.getOutputStream());
        } catch (Exception e) {
            LOG.error("将内存中的图片通过流动形式输出到客户端失败>>>>   ", e);
        }
    }
    public void write(HttpServletRequest request, HttpServletResponse response){
        request.getSession().removeAttribute(SESSION_PARAM_PICCODE);
        request.getSession().setAttribute(SESSION_PARAM_PICCODE,code);
        try {
            // 将内存中的图片通过流动形式输出到客户端
            ImageIO.write(buffImg, "JPEG", response.getOutputStream());
        } catch (Exception e) {
            LOG.error("将内存中的图片通过流动形式输出到客户端失败>>>>   ", e);
        }
    }

    /**
     * 获得字体
     */
    private Font getFont() {
        return new Font("Fixedsys", Font.CENTER_BASELINE, 18);
    }

    /**
     * 获得颜色
     */
    private Color getRandColor(int fc, int bc) {
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc - 16);
        int g = fc + random.nextInt(bc - fc - 14);
        int b = fc + random.nextInt(bc - fc - 18);
        return new Color(r, g, b);
    }
    /**
     * 绘制干扰线
     */
    private void drowLine(Graphics g) {
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        int xl = random.nextInt(13);
        int yl = random.nextInt(15);
        g.drawLine(x, y, x + xl, y + yl);
    }


    /**
     * 绘制字符串
     */
    private String drowString(Graphics g, int i) {
        g.setFont(getFont());
        g.setColor(new Color(random.nextInt(101), random.nextInt(111), random
                .nextInt(121)));
        String rand = String.valueOf(getRandomString());
        g.translate(random.nextInt(3), random.nextInt(3));
        g.drawString(rand, 13 * i, 16);
        return rand;
    }

    /**
     * 绘制字符串
     */
    private void drowString(Graphics g, int i, String str) {
        g.setFont(getFont());
        g.setColor(new Color(random.nextInt(101), random.nextInt(111), random
                .nextInt(121)));
        g.translate(random.nextInt(3), random.nextInt(3));
        g.drawString(str, 13 * i, 16);
    }

    /**
     * 获取随机的字符
     */
    public String getRandomString() {
        if (onlyNum){
            return String.valueOf(randNum.charAt(random.nextInt(randNum.length())));
        }
        return String.valueOf(randStr.charAt(random.nextInt(randStr.length())));
    }


    public void write(String path) throws IOException {
        OutputStream sos = new FileOutputStream(path);
        this.write(sos);
    }

    public void write(OutputStream sos) throws IOException {
//        ImageIO.write(buffImg, "png", sos);
        ImageIO.write(buffImg, "jpeg", sos);
        sos.close();
    }

    public static void main(String[] args) {
        PicAuthImg pai = new PicAuthImg(5,true);
        String path="D:/"+new Date().getTime()+".png";
        System.out.println(pai.getCode()+" >"+path);
        try {
            pai.write(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


你可能感兴趣的:(JAVA,图形验证码,java,数字)