基于Java生成圖片驗證碼的方法解析
使用Java生成圖片驗證碼完全解析
在 Java 中開發(fā)圖片驗證碼功能,您可以使用 Java 圖形處理庫,比如 Java Advanced Imaging (JAI) 或者 Java2D,來生成圖片并將文本寫入圖片。具體實現(xiàn)方法如下:
- 創(chuàng)建一個 BufferedImage 對象,并設置圖片的寬度和高度。
- 獲取圖片的 Graphics2D 對象,并設置文本的顏色和字體。
- 在圖片上繪制文本。
- 對圖片進行一些隨機處理,比如加入干擾線、噪點等,以增加圖片驗證碼的難度。
- 將圖片輸出到瀏覽器,并設置相應的 Content-Type?;蛘邔ufferedImage轉為base64編碼輸出到瀏覽器。(本次統(tǒng)一輸出到文件)

下面是一個簡單的示例代碼,可以幫助您快速開始:
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
public class Captcha {
public static void main(String[] args) throws Exception {
int width = 100;
int height = 40;
// 創(chuàng)建 BufferedImage 對象
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 獲取圖片的 Graphics2D 對象
Graphics2D g = image.createGraphics();
// 設置文本的顏色和字體
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.BOLD, 20));
// 繪制文本
g.drawString("Hello, World!", 10, 30);
// 釋放 Graphics2D 對象
g.dispose();
// 將圖片輸出到瀏覽器
ImageIO.write(image, "jpeg", new File("captcha.jpeg"));
}
}注意事項
在您的應用中使用圖片驗證碼功能時,需要注意以下幾點:
- 在生成圖片驗證碼時,需要使用隨機數(shù)生成文本內容,以保證每次生成的圖片都是不同的。
- 在生成圖片時,需要使用足夠復雜的算法來生成干擾線和噪點,以增加圖片驗證碼的難度。
- 在向用戶展示圖片驗證碼時,需要將圖片的文本內容存儲在服務器端,以便在用戶提交表單時進行驗證。
- 在驗證用戶輸入的圖片驗證碼時,需要注意大小寫敏感問題,并且需要考慮用戶輸入的可能存在的誤差。
如何加入噪點
在 Java 中加入噪點可以使用隨機數(shù)生成噪點的位置和顏色,然后使用 Graphics2D 的 drawLine() 方法在圖片上繪制噪點。

例如,下面的代碼演示了如何在圖片上隨機繪制 100 個噪點:
import java.awt.*;
import java.awt.image.*;
import java.util.Random;
public class Captcha {
public static void main(String[] args) throws Exception {
int width = 100;
int height = 40;
// 創(chuàng)建 BufferedImage 對象
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 獲取圖片的 Graphics2D 對象
Graphics2D g = image.createGraphics();
// 設置文本的顏色和字體
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.BOLD, 20));
// 繪制文本
g.drawString("Hello, World!", 10, 30);
// 創(chuàng)建隨機數(shù)生成器
Random rnd = new Random();
// 繪制噪點
for (int i = 0; i < 100; i++) {
int x = rnd.nextInt(width);
int y = rnd.nextInt(height);
g.drawLine(x, y, x, y);
}
// 釋放 Graphics2D 對象
g.dispose();
}
}
上面的代碼中,我們使用了隨機數(shù)生成噪點的位置和顏色,并使用 Graphics2D 的 drawLine() 方法在圖片上繪制噪點。
如何生成干擾線
在 Java 中生成干擾線可以使用隨機數(shù)生成干擾線的起始點和結束點,然后使用 Graphics2D 的 drawLine() 方法在圖片上繪制干擾線。

例如,下面的代碼演示了如何在圖片上隨機繪制 10 條干擾線:
import java.awt.*;
import java.awt.image.*;
import java.util.Random;
public class Captcha {
public static void main(String[] args) throws Exception {
int width = 100;
int height = 40;
// 創(chuàng)建 BufferedImage 對象
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 獲取圖片的 Graphics2D 對象
Graphics2D g = image.createGraphics();
// 設置文本的顏色和字體
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.BOLD, 20));
// 繪制文本
g.drawString("Hello, World!", 10, 30);
// 創(chuàng)建隨機數(shù)生成器
Random rnd = new Random();
// 繪制干擾線
for (int i = 0; i < 10; i++) {
int x1 = rnd.nextInt(width);
int y1 = rnd.nextInt(height);
int x2 = rnd.nextInt(width);
int y2 = rnd.nextInt(height);
g.drawLine(x1, y1, x2, y2);
}
// 釋放 Graphics2D 對象
g.dispose();
}
}上面的代碼中,我們使用了隨機數(shù)生成干擾線的起始點和結束點,并使用 Graphics2D 的 drawLine() 方法在圖片上繪制干擾線。到了這一步其實大多數(shù)OCR已經(jīng)不能識別了。
什么樣的算法生成噪點比較好
在生成噪點時,最重要的是要保證噪點數(shù)量足夠多,以增加圖片驗證碼的難度。您可以使用以下算法來生成噪點:
- 在圖片的所有像素點上隨機繪制一定數(shù)量的噪點。這種方法可以保證噪點數(shù)量足夠多,但會使圖片變得很雜亂,不利于用戶識別。
- 在圖片的一部分像素點上隨機繪制噪點。這種方法可以使圖片看起來清晰一些,但需要調整噪點的數(shù)量,以保證噪點數(shù)量足夠多。
- 使用圖形生成算法生成噪點。這種方法可以生成較為復雜的噪點圖形,但需要較多的計算資源。
最終選擇哪種方法取決于您的需求和系統(tǒng)的性能。
在 Java 中使用圖形生成算法生成噪點,可以使用 Java2D 庫中的 Shape 接口和相關的實現(xiàn)類來生成各種圖形。例如,使用 Ellipse2D 類可以生成橢圓形噪點,使用 Rectangle2D 類可以生成矩形噪點。

下面是一個簡單的示例代碼,演示了如何使用圖形生成算法生成噪點:
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.Random;
public class Captcha {
public static void main(String[] args) throws Exception {
int width = 100;
int height = 40;
// 創(chuàng)建 BufferedImage 對象
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 獲取圖片的 Graphics2D 對象
Graphics2D g = image.createGraphics();
// 設置文本的顏色和字體
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.BOLD, 20));
// 繪制文本
g.drawString("Hello, World!", 10, 30);
// 創(chuàng)建隨機數(shù)生成器
Random rnd = new Random();
// 繪制噪點
for (int i = 0; i < 100; i++) {
Shape shape = new Ellipse2D.Double(rnd.nextDouble() * width, rnd.nextDouble() * height, rnd.nextDouble() * 5 + 1, rnd.nextDouble() * 5 + 1);
g.fill(shape);
}
// 釋放 Graphics2D 對象
g.dispose();
}
}驗證碼如何避免被ocr識別
為了避免驗證碼被 OCR (Optical Character Recognition, 光學字符識別) 軟件識別,可以使用以下幾種方法:
- 增加噪點:在圖片中加入噪點(如隨機點、線條等),使 OCR 軟件難以準確識別文本。
- 斜放文本:將文本斜放,使 OCR 軟件難以識別。
- 改變字體:使用特殊的字體,使 OCR 軟件難以識別。
- 變換顏色:改變文本的顏色,使 OCR 軟件難以識別。
- 增加干擾元素:在圖片中加入干擾元素(如干擾線、干擾圖案等),使 OCR 軟件難以準確識別文本。
如何斜放文本
單純的斜放文本只能避免某一些OCR算法,最好是每個字符都傾斜不同的角度。并且保持不同的間距。
在 Java 中斜放文本可以使用 Graphics2D 的 rotate() 方法來旋轉文本。例如,下面的代碼演示了如何在圖片上斜放文本:

import java.awt.*;
import java.awt.image.*;
public class Captcha {
public static void main(String[] args) throws Exception {
int width = 100;
int height = 40;
// 創(chuàng)建 BufferedImage 對象
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 獲取圖片的 Graphics2D 對象
Graphics2D g = image.createGraphics();
// 設置文本的顏色和字體
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.BOLD, 20));
// 旋轉文本
g.rotate(Math.toRadians(30), width / 2, height / 2);
// 繪制文本
g.drawString("Hello, World!", 10, 30);
// 釋放 Graphics2D 對象
g.dispose();
}
}上面的代碼中,我們使用 Graphics2D 的 rotate() 方法將文本旋轉了 30 度。注意,旋轉角度使用的是弧度制,所以需要使用 Math.toRadians() 方法將角度轉換為弧度。
四位圖形驗證碼
實現(xiàn)一個支持圖形干擾算法,斜放文本,使用特殊的字體,動態(tài)文本的顏色的四位圖形驗證碼

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.Random;
public class Captcha {
private static final char[] CHARS = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'
};
private static Random rnd = new Random();
public static String generateText() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 4; i++) {
sb.append(CHARS[rnd.nextInt(CHARS.length)]);
}
return sb.toString();
}
public static Color generateColor() {
return new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
}
public static void main(String[] args) throws Exception {
int width = 120;
int height = 40;
// 創(chuàng)建 BufferedImage 對象
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 獲取圖片的 Graphics2D 對象
Graphics2D g = image.createGraphics();
// 繪制背景
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
// 繪制文本
String text = generateText();
g.setFont(new Font("Arial", Font.BOLD, 20));
g.setColor(generateColor());
g.rotate(Math.toRadians(30), width / 2, height / 2);
g.drawString(text, 10, 30);
// 繪制噪點
for (int i = 0; i < 100; i++) {
Shape shape = new Ellipse2D.Double(rnd.nextDouble() * width, rnd.nextDouble() * height, rnd.nextDouble() * 5 + 1, rnd.nextDouble() * 5 + 1);
g.setColor(generateColor());
g.fill(shape);
}
// 繪制干擾線
for (int i = 0; i < 5; i++) {
g.setColor(generateColor());
g.drawLine(rnd.nextInt(width), rnd.nextInt(height), rnd.nextInt(width), rnd.nextInt(height));
}
// 釋放 Graphics2D 對象
g.dispose();
// 輸出圖片
ImageIO.write(image, "PNG", new File("captcha.png"));
}
}上面的代碼中,我們使用了 Ellipse2D 類生成橢圓形噪點,并使用隨機數(shù)生成噪點的位置和大小。我們還使用了 drawLine() 方法生成干擾線,并使用隨機數(shù)生成干擾線的位置和長度。
可以看到,雖然安全性提高了,但是辨識很困難。
調整噪點的透明度
在 Java 中調整噪點的透明度可以使用 AlphaComposite 類的靜態(tài)方法 getInstance() 來創(chuàng)建 AlphaComposite 對象,然后使用 setComposite() 方法來設置透明度。例如,下面的代碼演示了如何調整噪點的透明度:

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.Random;
public class Captcha {
private static final char[] CHARS = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'
};
private static Random rnd = new Random();
public static String generateText() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 4; i++) {
sb.append(CHARS[rnd.nextInt(CHARS.length)]);
}
return sb.toString();
}
public static Color generateColor() {
return new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
}
public static void main(String[] args) throws Exception {
int width = 120;
int height = 40;
// 創(chuàng)建 BufferedImage 對象
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 獲取圖片的 Graphics2D 對象
Graphics2D g = image.createGraphics();
// 繪制背景
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
// 繪制文本
String text = generateText();
g.setFont(new Font("Arial", Font.BOLD, 20));
g.setColor(generateColor());
g.rotate(Math.toRadians(30), width / 2, height / 2);
g.drawString(text, 10, 30);
// 調整噪點的透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
// 繪制噪點
for (int i = 0; i < 100; i++) {
Shape shape = new Ellipse2D.Double(rnd.nextDouble() * width, rnd.nextDouble() * height, rnd.nextDouble() * 5 + 1, rnd.nextDouble() * 5 + 1);
g.setColor(generateColor());
g.fill(shape);
}
// 繪制干擾線
for (int i = 0; i < 5; i++) {
g.setColor(generateColor());
g.drawLine(rnd.nextInt(width), rnd.nextInt(height), rnd.nextInt(width), rnd.nextInt(height));
}
// 釋放 Graphics2D 對象
g.dispose();
// 輸出圖片
ImageIO.write(image, "PNG", new File("captcha.png"));
}
}到此這篇關于基于Java生成圖片驗證碼的方法解析的文章就介紹到這了,更多相關Java圖片驗證碼內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java中l(wèi)ist集合為空或為null的區(qū)別說明
這篇文章主要介紹了Java中l(wèi)ist集合為空或為null的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
IDEA配置Gradle及Gradle安裝的實現(xiàn)步驟
本文主要介紹了IDEA配置Gradle及Gradle安裝的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-08-08
Log4j2?重大漏洞編譯好的log4j-2.15.0.jar包下載(替換過程)
Apache?開源項目?Log4j?的遠程代碼執(zhí)行漏洞細節(jié)被公開,由于?Log4j?的廣泛使用,該漏洞一旦被攻擊者利用會造成嚴重危害,下面小編給大家?guī)砹薒og4j2?重大漏洞編譯好的log4j-2.15.0.jar包下載,感興趣的朋友一起看看吧2021-12-12

