zoukankan      html  css  js  c++  java
  • 生成图片验证码工具类 Base64处理

    加了一个转成了Base64编码。,其他的和网上一样。

      1 public class ValidateCodeUtil {
      2 
      3     // 图片的宽度。
      4     private int width = 160;
      5     // 图片的高度。
      6     private int height = 40;
      7     // 验证码字符个数
      8     private int codeCount = 5;
      9     // 验证码干扰线数
     10     private int lineCount = 150;
     11     // 验证码
     12     private String code = null;
     13     // 验证码图片Buffer
     14     private BufferedImage buffImg = null;
     15 
     16     private String base64 = null;
     17 
     18     public String getBase64() {
     19         try {
     20             base64 = getBase64(buffImg);
     21         } catch (Exception e) {
     22             System.out.println("转换失败");
     23         }
     24         return base64;
     25     }
     26 
     27     // 验证码范围,去掉0(数字)和O(拼音)容易混淆的(小写的1和L也可以去掉,大写不用了)
     28     private char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
     29             'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
     30             'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
     31 
     32     /**
     33      * 默认构造函数,设置默认参数
     34      */
     35     public ValidateCodeUtil() {
     36         this.createCode();
     37     }
     38 
     39     /**
     40      * @param width  图片宽
     41      * @param height 图片高
     42      */
     43     public ValidateCodeUtil(int width, int height) {
     44         this.width = width;
     45         this.height = height;
     46         this.createCode();
     47     }
     48 
     49     /**
     50      * @param width     图片宽
     51      * @param height    图片高
     52      * @param codeCount 字符个数
     53      * @param lineCount 干扰线条数
     54      */
     55     public ValidateCodeUtil(int width, int height, int codeCount, int lineCount) {
     56         this.width = width;
     57         this.height = height;
     58         this.codeCount = codeCount;
     59         this.lineCount = lineCount;
     60         this.createCode();
     61     }
     62 
     63     public void createCode() {
     64         int x = 0, fontHeight = 0, codeY = 0;
     65         int red = 0, green = 0, blue = 0;
     66 
     67         x = width / (codeCount + 2);//每个字符的宽度(左右各空出一个字符)
     68         fontHeight = height - 2;//字体的高度
     69         codeY = height - 4;
     70 
     71         // 图像buffer
     72         buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
     73         Graphics2D g = buffImg.createGraphics();
     74 
     75         /*// 将图像背景填充为白色
     76         g.setColor(Color.WHITE);
     77         g.fillRect(0, 0, width, height);*/
     78         // 增加下面代码使得背景透明
     79         buffImg = g.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
     80         g.dispose();
     81         g = buffImg.createGraphics();
     82         // 背景透明代码结束
     83 
     84         // 画图BasicStroke是JDK中提供的一个基本的画笔类,我们对他设置画笔的粗细,就可以在drawPanel上任意画出自己想要的图形了。
     85         g.setColor(new Color(255, 0, 0));
     86         g.setStroke(new BasicStroke(1f));
     87         g.fillRect(128, 128, width, height);
     88 
     89         // 生成随机数
     90         Random random = new Random();
     91         //设置字体类型、字体大小、字体样式 
     92         Font font = new Font("微软雅黑", Font.PLAIN, fontHeight);
     93 
     94         g.setFont(font);
     95 
     96         for (int i = 0; i < lineCount; i++) {
     97             // 设置随机开始和结束坐标
     98             int xs = random.nextInt(width);//x坐标开始
     99             int ys = random.nextInt(height);//y坐标开始
    100             int xe = xs + random.nextInt(width / 8);//x坐标结束
    101             int ye = ys + random.nextInt(height / 8);//y坐标结束
    102 
    103             // 产生随机的颜色值,让输出的每个干扰线的颜色值都将不同。
    104             red = random.nextInt(255);
    105             green = random.nextInt(255);
    106             blue = random.nextInt(255);
    107             g.setColor(new Color(red, green, blue));
    108             g.drawLine(xs, ys, xe, ye);
    109         }
    110 
    111         // randomCode记录随机产生的验证码
    112         StringBuffer randomCode = new StringBuffer();
    113         // 随机产生codeCount个字符的验证码。
    114         for (int i = 0; i < codeCount; i++) {
    115             String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);
    116             // 产生随机的颜色值,让输出的每个字符的颜色值都将不同。
    117             red = random.nextInt(255);
    118             green = random.nextInt(255);
    119             blue = random.nextInt(255);
    120             //指定某种颜色
    121             //g.setColor(new Color(252, 145, 83));
    122             g.setColor(new Color(red, green, blue));
    123             g.drawString(strRand, (i + 1) * x, codeY);
    124             // 将产生的四个随机数组合在一起。
    125             randomCode.append(strRand);
    126         }
    127         // 将四位数字的验证码保存到Session中。
    128         code = randomCode.toString();
    129     }
    130 
    131     public void write(String path) throws IOException {
    132         OutputStream sos = new FileOutputStream(path);
    133         this.write(sos);
    134     }
    135 
    136     public void write(OutputStream sos) throws IOException {
    137         ImageIO.write(buffImg, "png", sos);
    138         sos.close();
    139     }
    140 
    141     public BufferedImage getBuffImg() {
    142         return buffImg;
    143     }
    144 
    145     public String getCode() {
    146         return code;
    147     }
    148 
    149     public static void main(String[] args) {
    150         ValidateCodeUtil vCode = new ValidateCodeUtil();
    151         Map<String, Object> map = new HashMap<>(16);
    152         map.put("code",vCode.getCode());
    153         map.put("image",vCode.getBase64());
    154         System.out.println(map);
    155     }
    156 
    157     /**
    158      * 转换成图片格式
    159      * @param buffImg
    160      * @return
    161      * @throws Exception
    162      */
    163     private static String getBase64(BufferedImage buffImg) throws Exception {
    164         ByteArrayOutputStream out = new ByteArrayOutputStream();
    165         ImageIO.write(buffImg, "png", out);
    166         byte[] bytes = out.toByteArray();
    167         out.close();
    168         String base64bytes = "data:image/png;base64," + Base64Util.encode(bytes);
    169         return base64bytes;
    170     }
    171 }

    Base64Util

      1 public class Base64Util {
      2 
      3     static private final int BASELENGTH = 128;
      4     static private final int LOOKUPLENGTH = 64;
      5     static private final int TWENTYFOURBITGROUP = 24;
      6     static private final int EIGHTBIT = 8;
      7     static private final int SIXTEENBIT = 16;
      8     static private final int FOURBYTE = 4;
      9     static private final int SIGN = -128;
     10     static private final char PAD = '=';
     11     static private final boolean fDebug = false;
     12     static final private byte[] base64Alphabet = new byte[BASELENGTH];
     13     static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
     14 
     15 
     16     static {
     17         for (int i = 0; i < BASELENGTH; ++i) {
     18             base64Alphabet[i] = -1;
     19         }
     20         for (int i = 'Z'; i >= 'A'; i--) {
     21             base64Alphabet[i] = (byte) (i - 'A');
     22         }
     23         for (int i = 'z'; i >= 'a'; i--) {
     24             base64Alphabet[i] = (byte) (i - 'a' + 26);
     25         }
     26 
     27         for (int i = '9'; i >= '0'; i--) {
     28             base64Alphabet[i] = (byte) (i - '0' + 52);
     29         }
     30 
     31         base64Alphabet['+'] = 62;
     32         base64Alphabet['/'] = 63;
     33 
     34         for (int i = 0; i <= 25; i++) {
     35             lookUpBase64Alphabet[i] = (char) ('A' + i);
     36         }
     37 
     38         for (int i = 26, j = 0; i <= 51; i++, j++) {
     39             lookUpBase64Alphabet[i] = (char) ('a' + j);
     40         }
     41 
     42         for (int i = 52, j = 0; i <= 61; i++, j++) {
     43             lookUpBase64Alphabet[i] = (char) ('0' + j);
     44         }
     45         lookUpBase64Alphabet[62] = (char) '+';
     46         lookUpBase64Alphabet[63] = (char) '/';
     47 
     48     }
     49 
     50 
     51     /**
     52      * base64 编码
     53      *
     54      * @param str
     55      * @return
     56      */
     57     public static String encoder(String str) {
     58         final Base64.Encoder encoder = Base64.getEncoder();
     59         String strEncoder = null;
     60         try {
     61             strEncoder = encoder.encodeToString(str.getBytes("UTF-8"));
     62         } catch (UnsupportedEncodingException e) {
     63             e.printStackTrace();
     64         }
     65         return strEncoder;
     66     }
     67 
     68     /**
     69      * Encodes hex octects into Base64 
     70      *
     71      * @param binaryData Array containing binaryData 
     72      * @return Encoded Base64 array 
     73      */
     74     public static String encode(byte[] binaryData) {
     75 
     76         if (binaryData == null) {
     77             return null;
     78         }
     79 
     80         int lengthDataBits = binaryData.length * EIGHTBIT;
     81         if (lengthDataBits == 0) {
     82             return "";
     83         }
     84 
     85         int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
     86         int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
     87         int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
     88         char encodedData[] = null;
     89 
     90         encodedData = new char[numberQuartet * 4];
     91 
     92         byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
     93 
     94         int encodedIndex = 0;
     95         int dataIndex = 0;
     96         if (fDebug) {
     97             System.out.println("number of triplets = " + numberTriplets);
     98         }
     99 
    100         for (int i = 0; i < numberTriplets; i++) {
    101             b1 = binaryData[dataIndex++];
    102             b2 = binaryData[dataIndex++];
    103             b3 = binaryData[dataIndex++];
    104 
    105             if (fDebug) {
    106                 System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);
    107             }
    108 
    109             l = (byte) (b2 & 0x0f);
    110             k = (byte) (b1 & 0x03);
    111 
    112             byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
    113             byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
    114             byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
    115 
    116             if (fDebug) {
    117                 System.out.println("val2 = " + val2);
    118                 System.out.println("k4   = " + (k << 4));
    119                 System.out.println("vak  = " + (val2 | (k << 4)));
    120             }
    121 
    122             encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
    123             encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
    124             encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
    125             encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
    126         }
    127 
    128         // form integral number of 6-bit groups  
    129         if (fewerThan24bits == EIGHTBIT) {
    130             b1 = binaryData[dataIndex];
    131             k = (byte) (b1 & 0x03);
    132             if (fDebug) {
    133                 System.out.println("b1=" + b1);
    134                 System.out.println("b1<<2 = " + (b1 >> 2));
    135             }
    136             byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
    137             encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
    138             encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
    139             encodedData[encodedIndex++] = PAD;
    140             encodedData[encodedIndex++] = PAD;
    141         } else if (fewerThan24bits == SIXTEENBIT) {
    142             b1 = binaryData[dataIndex];
    143             b2 = binaryData[dataIndex + 1];
    144             l = (byte) (b2 & 0x0f);
    145             k = (byte) (b1 & 0x03);
    146 
    147             byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
    148             byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
    149 
    150             encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
    151             encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
    152             encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
    153             encodedData[encodedIndex++] = PAD;
    154         }
    155         return new String(encodedData);
    156     }
    157 
    158     /**
    159      * base64 解码
    160      *
    161      * @param str
    162      * @return
    163      */
    164     public static String decoder(String str) {
    165         final Base64.Decoder decoder = Base64.getDecoder();
    166         String strEncoder = null;
    167         try {
    168             strEncoder = new String(decoder.decode(str), "UTF-8");
    169         } catch (UnsupportedEncodingException e) {
    170             e.printStackTrace();
    171         }
    172         return strEncoder;
    173     }
    174 
    175 }

    运行实例:

    {
    image=  //图片
    data:image/png;base64,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
    , code=  //验证码
    P3V44
    }

    复制image结果到浏览器:

  • 相关阅读:
    数据库范式
    java String.split()用法
    1.4 IoC控制反转
    利用shrinkwrap锁定依赖版本
    清晨开启电脑自动拉取项目更新
    JS如何获取屏幕、浏览器及网页高度宽度?
    Navigator 对象,能够清楚地知道浏览器的相关信息
    iconfont 转换为图标字体
    VS code的搜索、替换与正则替换
    点九图制作方法
  • 原文地址:https://www.cnblogs.com/cmmplb/p/12499170.html
Copyright © 2011-2022 走看看