我们来设计一个简单的验证码生成程序:验证码一个由4位的数字、字母随机组合而成图像,为了避免被光学字元识别(OCR,Optical Character Recognition)之类的程序识别出图片中的数字而失去效果,我们给图像中添加上几条干扰线。
1 package password;
2 /**
3 * 使用Java设计验证码生成程序
4 * @author hellokitty燕
5 */
6 import java.awt.Color;
7 import java.awt.Font;
8 import java.awt.Graphics;
9 import java.awt.Graphics2D;
10 import java.awt.image.BufferedImage;
11 import java.util.Random;
12
13 import javax.swing.ImageIcon;
14 import javax.swing.JFrame;
15 import javax.swing.JLabel;
16
17 public class Verification {
18
19 /*验证码的框*/
20 // 图像长度
21 private int width = 100;
22 // 图像宽度
23 private int height = 40;
24 // 验证码的长度
25 private int number = 4;
26 // 验证码随机生成的
27 private String password = "abcdefghijkmnpqrstuvwxyABCDEFGHIJKLMNPQRSTUVWXYZ23456789";
28
29 /**
30 * 获取验证码图像
31 *
32 * @return 验证码图像
33 */
34 public BufferedImage getImage() {
35 /*BufferedImage 子类描述具有可访问图像数据缓冲区的 Image。
36 * BufferedImage(int width, int height, int imageType)构造一个类型为预定义图像类型之一的 BufferedImage。
37 *
38 * */
39 // 创建图像缓冲区
40 BufferedImage image = new BufferedImage(width, height,
41 BufferedImage.TYPE_INT_RGB);
42 // 获取画笔
43 /*public Graphics getGraphics()*/
44 Graphics g = image.getGraphics();
45
46 // 设置图像背景色,填充背景矩形
47 /*public abstract void setColor(Color c)*/
48
49
50 g.setColor(getRandomColor(200, 255));//???
51 /*public abstract void fillRect(int x,int y,int width,int height)*/
52 g.fillRect(0, 0, width, height);
53
54 // 画边框
55 g.setColor(Color.blue);
56 g.drawRect(0, 0, width - 1, height - 1);
57
58 /* 生成随机验证码 */
59 int len = password.length();
60 // 设置验证码字体 Font(String name, int style, int size)
61 // HANGING_BASELINE 布置文本时,在 Devanigiri 和类似脚本中使用的基线。
62 g.setFont(new Font("楷体", Font.HANGING_BASELINE, 20));
63
64 // 循环生成验证码各字符????
65 Random random = new Random();
66 for (int i = 0; i < number; i++) {
67 // 随机生成验证码中单个字符/*public int nextInt(int n)返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值*/
68 String randStr = String.valueOf(password.charAt(random.nextInt(len)));
69 // 单个字符绘制宽度
70 int width = this.width / this.number;
71 // 当前字符绘制原点 ????
72 int x = width * i;
73 int y = this.height / 2 + random.nextInt(this.height / 3);
74 /* 将该字符画到图像中 */// ???
75 drawString(g, x, y, randStr);
76
77 }
78
79 // 画干扰线
80 drawLine(g, 10);
81
82 // 释放画笔
83 g.dispose();
84 return image;
85
86 }
87
88 /**
89 * 画验证码字符串单个字符
90 *
91 * @param g
92 * 图像上下文
93 * @param x
94 * 字符 所占宽度
95 * @param y
96 * 字符所占高度
97 * @param randStr
98 * 待绘制字符串
99 *
100 */
101 private void drawString(Graphics g,int width,int height,String randStr){
102 //private void drawString(Graphics g, int x, int y, String randStr) {
103 Random rand = new Random();
104 // 随机生成字符旋转(-30-30度)/*/*public int nextInt(int n)返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值*/*/
105 int degree = rand.nextInt(60);
106 if (degree > 30) {
107 degree = 30 - degree;
108 }
109 // 设置字体颜色
110 g.setColor(getRandomColor(0, 50));
111 // 转换Graphics2D
112 Graphics2D g2 = (Graphics2D) g.create();
113 // 平移原点到图形环境的中心,这个方法的作用实际上就是将字符串移到某一位置/*public abstract void translate(int x,int y)将 Graphics2D 上下文的原点平移到当前坐标系中的点 (x, y)。*/
114 g2.translate(width + rand.nextInt(5), height + rand.nextInt(5));
115 // 旋转文本 ( 单位是弧度)
116 g2.rotate(degree * Math.PI / 180);
117 // 画文本,特别需要注意的是,这里的笔画已经具有上次指定的一个位置,所以这里指定的位置是一个相对的位置
118 g2.drawString(randStr, 0, 0);
119 }
120
121 /**
122 *
123 * 画 随机干扰线
124 *
125 * @param g
126 * 图形上下文(画笔)
127 *
128 * @param count
129 * 干扰线条数
130 */
131 private void drawLine(Graphics g,int count){
132
133 Random random = new Random();
134 // 循环绘制每条干扰线
135 for (int j = 0; j < count; j++) {
136 // 设置线条随机颜色
137 g.setColor(getRandomColor(180, 200));
138
139 // 生成随机线条起点终点,坐标点
140 int x1 = random.nextInt(this.width);
141 int y1 = random.nextInt(this.height);
142 int x2 = random.nextInt(this.width);
143 int y2 = random.nextInt(this.height);
144 // 画线条
145 g.drawLine(x1, y1, x2, y2);
146 }
147 }
148
149 /**
150 * 获取随机颜色
151 *
152 * @param i
153 * 颜色下限值
154 * @param j
155 * 颜色上限值
156 * @return 随机颜色对象
157 */
158 private Color getRandomColor(int i, int j) {
159 if (i > j) {
160 int tmp = i;
161 i = j;
162 j = tmp;
163 }
164 if (j > 225) {
165 j = 225;
166 }
167 if (i < 0) {
168 i = 0;
169 }
170 int r = i + (int) (Math.random() * (j - i));
171 int g = i + (int) (Math.random() * (j - i));
172 int b = i + (int) (Math.random() * (j - i));
173
174 return new Color(r, g, b);
175
176 // values in the range (0 - 255). red green blue
177 }
178
179 public static void main(String[] args) {
180
181 JFrame frame = new JFrame("验证码");
182 frame.setSize(200, 200);
183 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
184 frame.setLocationRelativeTo(null);
185 Verification cation = new Verification();
186
187 JLabel lbl = new JLabel(new ImageIcon(cation.getImage()));
188 frame.add(lbl);
189 frame.setVisible(true);
190
191 }
192
193 }