我们来设计一个简单的验证码生成程序:验证码一个由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 }