peter
2025-07-11 19be3926c88d19645f43dd926d00615225f30802
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package com.yami.trading.common.util;
 
 
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
 
import javax.imageio.ImageIO;
import javax.xml.bind.DatatypeConverter;
 
public class ImageVerificationCodeUtil {
    private int weight = 100; // 验证码图片的长和宽
    private int height = 40;
    private String text; // 用来保存验证码的文本内容
    private Random r = new Random(); // 获取随机数对象
    // private String[] fontNames = {"宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312"};
    // //字体数组
    // 字体数组
    private String[] fontNames = { "Georgia" };
    // 验证码数组
    private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
//    private String codes = "用来保存验证码的文本内容";
 
    /**
     * 获取随机的颜色
     *
     * @return
     */
    private Color randomColor() {
        int r = this.r.nextInt(225); // 这里为什么是225,因为当r,g,b都为255时,即为白色,为了好辨认,需要颜色深一点。
        int g = this.r.nextInt(225);
        int b = this.r.nextInt(225);
        return new Color(r, g, b); // 返回一个随机颜色
    }
 
    /**
     * 获取随机字体
     *
     * @return
     */
    private Font randomFont() {
        int index = r.nextInt(fontNames.length); // 获取随机的字体
        String fontName = fontNames[index];
        int style = r.nextInt(4); // 随机获取字体的样式,0是无样式,1是加粗,2是斜体,3是加粗加斜体
        int size = r.nextInt(10) + 24; // 随机获取字体的大小
        return new Font(fontName, style, size); // 返回一个随机的字体
    }
 
    /**
     * 获取随机字符
     *
     * @return
     */
    private char randomChar() {
        int index = r.nextInt(codes.length());
        return codes.charAt(index);
    }
 
    /**
     * 画干扰线,验证码干扰线用来防止计算机解析图片
     *
     * @param image
     */
    private void drawLine(BufferedImage image) {
        int num = 5 + r.nextInt(10); // 定义干扰线的数量
        Graphics2D g = (Graphics2D) image.getGraphics();
        for (int i = 0; i < num; i++) {
            int x1 = r.nextInt(weight);
            int y1 = r.nextInt(height);
            int x2 = r.nextInt(weight);
            int y2 = r.nextInt(height);
            g.setColor(randomColor());
            g.drawLine(x1, y1, x2, y2);
        }
    }
 
    /**
     * 创建图片的方法
     *
     * @return
     */
    private BufferedImage createImage() {
        // 创建图片缓冲区
        BufferedImage image = new BufferedImage(weight, height, BufferedImage.TYPE_INT_RGB);
        // 获取画笔
        Graphics2D g = (Graphics2D) image.getGraphics();
        // 设置背景色随机
        g.setColor(new Color(255, 255, r.nextInt(245) + 10));
        g.fillRect(0, 0, weight, height);
        // 返回一个图片
        return image;
    }
 
    /**
     * 获取验证码图片的方法
     *
     * @return
     */
    public BufferedImage getImage() {
        BufferedImage image = createImage();
        Graphics2D g = (Graphics2D) image.getGraphics(); // 获取画笔
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 4; i++) // 画四个字符即可
        {
            String s = randomChar() + ""; // 随机生成字符,因为只有画字符串的方法,没有画字符的方法,所以需要将字符变成字符串再画
            sb.append(s); // 添加到StringBuilder里面
            float x = i * 1.0F * weight / 4; // 定义字符的x坐标
            g.setFont(randomFont()); // 设置字体,随机
            g.setColor(randomColor()); // 设置颜色,随机
            g.drawString(s, x, height - 5);
        }
        this.text = sb.toString();
        drawLine(image);
        return image;
    }
 
    public String getBase64() {
        BufferedImage image = this.getImage();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "JPEG", outputStream);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String data = "data:image/jpg;base64," + DatatypeConverter.printBase64Binary(outputStream.toByteArray());
        return data;
    }
 
    /**
     * 获取验证码文本的方法
     *
     * @return
     */
    public String getText() {
        return text;
    }
 
    public static void output(BufferedImage image, OutputStream out) throws IOException // 将验证码图片写出的方法
    {
        ImageIO.write(image, "JPEG", out);
    }
 
    public static void main(String[] args) {
        ImageVerificationCodeUtil ivc = new ImageVerificationCodeUtil(); // 用我们的验证码类,生成验证码类对象
        BufferedImage image = ivc.getImage(); // 获取验证码
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "JPEG", outputStream);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String data = "data:image/jpg;base64," + DatatypeConverter.printBase64Binary(outputStream.toByteArray());
        // System.out.println(data);
    }
}