图片验证码

做注册登陆需要图片验证码。

遂如下
 

package com.dtyunxi.jingbo.common.utils;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

import com.dtyunxi.jingbo.common.utils.redis.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("imageCode")
public class ImageCode {

   private int width = 125;
   private int height = 38;
   private int codeLength = 4;
   private String randomString = "ABCDEFGHIJKLMNPQRSTUVWXYZ23456789abcdefghijkmnpqrstuvwxyz";
   private String sessionKey = "SESSION_VCODE";
   private String fontName = "Times New Roman";
   private int fontStyle = 0;
   private int fontSize = 18;
   private Long expireTime = 900L;// 15分钟

   protected static final Logger logger = LoggerFactory.getLogger(ImageCode.class);

   private static final String IMGCODESTR = "imgCode:";

   @Autowired
   private RedisUtil redisManager;
   /*
    * 根据sessionId绑定图片验证码
    */
   public BufferedImage getImageWithSessionId(String keyCode) {
      // 在内存中创建图象
      BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
      // 获取图形上下文
      Graphics g = image.getGraphics();
      // 生成随机类
      Random random = new Random();
      // 设定背景色
      g.setColor(getRandColor(200, 250));
      g.fillRect(0, 0, width, height);
      // 设定字体
      g.setFont(new Font(fontName, fontStyle, fontSize));
      g.setColor(getRandColor(160, 200));
      for (int i = 0; i < 155; 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 sRand = randomRand(codeLength);// 取随机产生的认证码
      int strWidth = width / 2 - g.getFontMetrics().stringWidth(sRand) / codeLength - 24;
      int strHeight = height / 2 + 12;
      for (int i = 0; i < codeLength; i++) {
         String rand = sRand.substring(i, i + 1);
         // 将认证码显示到图象中
         g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));// 调用函数出来的颜色相同,
         int zz = new Random().nextInt(8);
         zz = zz % 2 == 0 ? zz - 10 : zz;
         g.drawString(rand, strWidth + (13 + 16 * i), strHeight + zz);
      }
      //request.getSession().setAttribute(sessionKey, sRand);
      g.dispose();
      return image;
   }

   /*
    * 根据sessionId绑定图片验证码
    */
   public BufferedImage getImageWithSessionId(Integer width_, Integer height_,
         Integer fontSize_, Integer codeLength_) {
      width_ = width_ == null ? width : width_;
      height_ = height_ == null ? height : height_;
      fontSize_ = fontSize_ == null ? fontSize : fontSize_;
      codeLength_ = codeLength_ == null ? codeLength : codeLength_;
      // 在内存中创建图象
      BufferedImage image = new BufferedImage(width_, height_, BufferedImage.TYPE_INT_RGB);
      // 获取图形上下文
      Graphics g = image.getGraphics();
      // 生成随机类
      Random random = new Random();
      // 设定背景色
      g.setColor(getRandColor(200, 250));
      g.fillRect(0, 0, width_, height_);
      // 设定字体
      Font f = new Font(fontName, fontStyle, fontSize_);
      g.setFont(f);
      g.setColor(getRandColor(160, 200));
      for (int i = 0; i < 155; 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 sRand = randomRand(codeLength_);// 取随机产生的认证码
      int strWidth = width_ / 2 - g.getFontMetrics().stringWidth(sRand) / codeLength_ - fontSize_;
      int strHeight = height_ / 2 + g.getFontMetrics(f).getHeight() / 4;
      for (int i = 0; i < codeLength_; i++) {
         String rand = sRand.substring(i, i + 1);
         // 将认证码显示到图象中
         g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));// 调用函数出来的颜色相同,
         g.drawString(rand, 13 * i + 6 + strWidth, strHeight);
      }
      //request.getSession().setAttribute(sessionKey, sRand);
      g.dispose();
      return image;
   }

   /*
    * 根据前端随机生成一个code码绑定图片验证码放在redis
    * 
    */
   public BufferedImage getImage(Integer width_, Integer height_, Integer fontSize_, Integer codeLength_,
         String imageKey) {
      width_ = width_ == null ? width : width_;
      height_ = height_ == null ? height : height_;
      fontSize_ = fontSize_ == null ? fontSize : fontSize_;
      codeLength_ = codeLength_ == null ? codeLength : codeLength_;
      // 在内存中创建图象
      BufferedImage image = new BufferedImage(width_, height_, BufferedImage.TYPE_INT_RGB);
      // 获取图形上下文
      Graphics g = image.getGraphics();
      // 生成随机类
      Random random = new Random();
      // 设定背景色
      g.setColor(getRandColor(200, 250));
      g.fillRect(0, 0, width_, height_);
      // 设定字体
      Font f = new Font(fontName, fontStyle, fontSize_);
      g.setFont(f);
      g.setColor(getRandColor(160, 200));
      for (int i = 0; i < 155; 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 sRand = randomRand(codeLength_);// 取随机产生的认证码
      int strWidth = width_ / 2 - g.getFontMetrics().stringWidth(sRand) / codeLength_ - fontSize_;
      int strHeight = height_ / 2 + g.getFontMetrics(f).getHeight() / 4;
      for (int i = 0; i < codeLength_; i++) {
         String rand = sRand.substring(i, i + 1);
         // 将认证码显示到图象中
         g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));// 调用函数出来的颜色相同,
         g.drawString(rand, 13 * i + 6 + strWidth, strHeight);
      }

      // 干扰线
   /* int lines = 2;
      for (int i = 0; i < lines; i++) {
         Color c = new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
         g.setColor(c);
         g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
      }*/
      String key = getKey(imageKey);
      redisManager.set(key, sRand, expireTime);
      g.dispose();
      return image;
   }

   public String getImageCode(String imageKey) {
      String key = getKey(imageKey);
      String values = redisManager.get(key);
      return values;

   }

   public void cleanImageCode(String imageKey) {
      String key = getKey(imageKey);
      redisManager.remove(key);
   }

   private String getKey(String imageKey) {
      return IMGCODESTR + imageKey;
   }

   private Color getRandColor(int fc, int bc) {// 给定范围获得随机颜色
      Random random = new Random();
      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 String randomRand(int n) {
      String rand = "";
      int len = randomString.length() - 1;
      double r;
      for (int i = 0; i < n; i++) {
         r = (Math.random()) * len;
         rand = rand + randomString.charAt((int) r);
      }
      return rand;
   }

}这是工具类。
@Autowired
private ImageCode imageCode;
/**
 * 校验图片验证码
 * @param imgCodeVO
 * @return
 */
public ResponseDTO validImageCode(ImgCodeVO imgCodeVO){
    String code = imageCode.getImageCode(imgCodeVO.getImageKey());
    if (StringUtils.isEmpty(code)) {
        return new ResponseDTO(false, ErrorInfos.ClientErr.VERIFYCODE_TOME_OUT.getError_info(), ErrorInfos.ClientErr.VERIFYCODE_TOME_OUT.getError_no());
    }
    // 不区分大小写
    Boolean isPass = code.equalsIgnoreCase(imgCodeVO.getImageCode());
    if (isPass) {
        // 验证失败,重新获取新的,就得验证码马上失效
        imageCode.cleanImageCode(imgCodeVO.getImageKey());
        return new ResponseDTO(true);
    }
    return new ResponseDTO(true);
}

/**
 * 获取图片验证码
 * @return
 */
public ResponseDTO getImageCode(){
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    String imageStr;
    UUID uuid =  UUID.randomUUID();
    String imageKey = uuid.toString();
    try {
        ImageIO.write(imageCode.getImage(125, 38, 18, 4, imageKey), "png", outputStream);
        imageStr = com.alibaba.druid.util.Base64.byteArrayToBase64(outputStream.toByteArray());
        //String imageStr = Base64.encodeBase64String(outputStream.toByteArray());
    } catch (IOException e) {
        return new ResponseDTO(false, ErrorInfos.ClientErr.VERIFYCODE_TOME_OUT.getError_info(), ErrorInfos.ClientErr.VERIFYCODE_TOME_OUT.getError_no());
    } finally {
        if (null != outputStream) {
            try {
                outputStream.close();
            } catch (IOException e) {
                return new ResponseDTO(false, ErrorInfos.ClientErr.VERIFYCODE_TOME_OUT.getError_info(), ErrorInfos.ClientErr.VERIFYCODE_TOME_OUT.getError_no());
            }
        }
    }
    ImgCodeDTO imgCodeDTO = new ImgCodeDTO();
    imgCodeDTO.setImageKey(imageKey);
    imgCodeDTO.setImageCodeBase(imageStr);
    return new ResponseDTO(imgCodeDTO);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值