我們使用Java來設計一個簡單的驗證碼生成程序:驗證碼一個由4位的數字、字母隨機組合而成圖像,為了避免被光學字元識別(OCR,Optical Character Recognition)之類的程序識別出圖片中的數字而失去效果,我們給圖像中添加上幾條干擾線。
package password;
/**
* 使用Java設計驗證碼生成程序
* @author hellokitty燕
*/
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Verification {
/*驗證碼的框*/
// 圖像長度
private int width = 100;
// 圖像寬度
private int height = 40;
// 驗證碼的長度
private int number = 4;
// 驗證碼隨機生成的
private String password = "abcdefghijkmnpqrstuvwxyABCDEFGHIJKLMNPQRSTUVWXYZ23456789";
/**
* 獲取驗證碼圖像
*
* @return 驗證碼圖像
*/
public BufferedImage getImage() {
/*BufferedImage 子類描述具有可訪問圖像數據緩沖區的 Image。
* BufferedImage(int width, int height, int imageType)構造一個類型為預定義圖像類型之一的 BufferedImage。
*
* */
// 創建圖像緩沖區
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// 獲取畫筆
/*public Graphics getGraphics()*/
Graphics g = image.getGraphics();
// 設置圖像背景色,填充背景矩形
/*public abstract void setColor(Color c)*/
g.setColor(getRandomColor(200, 255));//???
/*public abstract void fillRect(int x,int y,int width,int height)*/
g.fillRect(0, 0, width, height);
// 畫邊框
g.setColor(Color.blue);
g.drawRect(0, 0, width - 1, height - 1);
/* 生成隨機驗證碼 */
int len = password.length();
// 設置驗證碼字體 Font(String name, int style, int size)
// HANGING_BASELINE 布置文本時,在 Devanigiri 和類似腳本中使用的基線。
g.setFont(new Font("楷體", Font.HANGING_BASELINE, 20));
// 循環生成驗證碼各字符????
Random random = new Random();
for (int i = 0; i < number; i++) {
// 隨機生成驗證碼中單個字符/*public int nextInt(int n)返回一個偽隨機數,它是取自此隨機數生成器序列的、在 0(包括)和指定值(不包括)之間均勻分布的 int 值*/
String randStr = String.valueOf(password.charAt(random.nextInt(len)));
// 單個字符繪制寬度
int width = this.width / this.number;
// 當前字符繪制原點 ????
int x = width * i;
int y = this.height / 2 + random.nextInt(this.height / 3);
/* 將該字符畫到圖像中 */// ???
drawString(g, x, y, randStr);
}
// 畫干擾線
drawLine(g, 10);
// 釋放畫筆
g.dispose();
return image;
}
/**
* 畫驗證碼字符串單個字符
*
* @param g
* 圖像上下文
* @param x
* 字符 所占寬度
* @param y
* 字符所占高度
* @param randStr
* 待繪制字符串
*
*/
private void drawString(Graphics g,int width,int height,String randStr){
//private void drawString(Graphics g, int x, int y, String randStr) {
Random rand = new Random();
// 隨機生成字符旋轉(-30-30度)/*/*public int nextInt(int n)返回一個偽隨機數,它是取自此隨機數生成器序列的、在 0(包括)和指定值(不包括)之間均勻分布的 int 值*/*/
int degree = rand.nextInt(60);
if (degree > 30) {
degree = 30 - degree;
}
// 設置字體顏色
g.setColor(getRandomColor(0, 50));
// 轉換Graphics2D
Graphics2D g2 = (Graphics2D) g.create();
// 平移原點到圖形環境的中心,這個方法的作用實際上就是將字符串移到某一位置/*public abstract void translate(int x,int y)將 Graphics2D 上下文的原點平移到當前坐標系中的點 (x, y)。*/
g2.translate(width + rand.nextInt(5), height + rand.nextInt(5));
// 旋轉文本 ( 單位是弧度)
g2.rotate(degree * Math.PI / 180);
// 畫文本,特別需要注意的是,這裡的筆畫已經具有上次指定的一個位置,所以這裡指定的位置是一個相對的位置
g2.drawString(randStr, 0, 0);
}
/**
*
* 畫 隨機干擾線
*
* @param g
* 圖形上下文(畫筆)
*
* @param count
* 干擾線條數
*/
private void drawLine(Graphics g,int count){
Random random = new Random();
// 循環繪制每條干擾線
for (int j = 0; j < count; j++) {
// 設置線條隨機顏色
g.setColor(getRandomColor(180, 200));
// 生成隨機線條起點終點,坐標點
int x1 = random.nextInt(this.width);
int y1 = random.nextInt(this.height);
int x2 = random.nextInt(this.width);
int y2 = random.nextInt(this.height);
// 畫線條
g.drawLine(x1, y1, x2, y2);
}
}
/**
* 獲取隨機顏色
*
* @param i
* 顏色下限值
* @param j
* 顏色上限值
* @return 隨機顏色對象
*/
private Color getRandomColor(int i, int j) {
if (i > j) {
int tmp = i;
i = j;
j = tmp;
}
if (j > 225) {
j = 225;
}
if (i < 0) {
i = 0;
}
int r = i + (int) (Math.random() * (j - i));
int g = i + (int) (Math.random() * (j - i));
int b = i + (int) (Math.random() * (j - i));
return new Color(r, g, b);
// values in the range (0 - 255). red green blue
}
public static void main(String[] args) {
JFrame frame = new JFrame("驗證碼");
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
Verification cation = new Verification();
JLabel lbl = new JLabel(new ImageIcon(cation.getImage()));
frame.add(lbl);
frame.setVisible(true);
}
}