Java生成條形碼和二維碼的完整指南
本文將詳細介紹如何在Java中生成條形碼和二維碼。條形碼要求在下方附加編號,二維碼需要支持更換中間logo、自定義顏色和樣式。我們將使用 zxing(Zebra Crossing)庫來實現(xiàn)這些功能,因為它是一個強大且開源的庫,支持多種條碼類型和自定義選項。本文包含依賴配置、代碼實現(xiàn)、詳細解釋和一個完整的可實際應用的工具類。
1. 依賴配置
首先,我們需要添加 zxing 庫的依賴。推薦使用Maven進行依賴管理。在項目的 pom.xml 文件中添加以下依賴:
<dependencies>
<!-- ZXing核心庫 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.5.3</version>
</dependency>
<!-- ZXing Java SE綁定,提供圖像生成功能 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.5.3</version>
</dependency>
</dependencies>
這些依賴提供了條形碼和二維碼生成的核心功能。core 庫處理編碼邏輯,javase 庫提供圖像渲染支持。
2. 條形碼生成實現(xiàn)
條形碼(如Code 128)是一種線性編碼,常用于商品標簽。我們將實現(xiàn)生成條形碼圖像并在下方附加編號的功能。
2.1 條形碼生成原理
- 編碼類型:我們使用
Code128Writer生成Code 128條形碼,這是一種廣泛支持的高密度編碼。 - 圖像生成:通過
BitMatrix表示條碼矩陣,然后渲染為BufferedImage。 - 添加編號:使用Java的
Graphics2D在圖像下方繪制文本。
2.2 代碼實現(xiàn)
以下方法生成條形碼并添加編號:
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.oned.Code128Writer;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
public class BarcodeGenerator {
/**
* 生成條形碼圖像并在下方附加編號。
*
* @param data 條形碼數(shù)據(jù)(如商品ID)
* @param textBelow 條形碼下方顯示的文本(編號)
* @param width 圖像寬度(像素)
* @param height 圖像高度(像素),不包括文本區(qū)域
* @return 生成的BufferedImage對象
* @throws WriterException 如果編碼失敗
*/
public static BufferedImage generateBarcode(String data, String textBelow, int width, int height) throws WriterException {
// 設置編碼提示(可選),例如設置邊距
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.MARGIN, 10); // 設置邊距為10像素
// 創(chuàng)建Code128Writer實例并生成BitMatrix
Code128Writer writer = new Code128Writer();
BitMatrix bitMatrix = writer.encode(data, BarcodeFormat.CODE_128, width, height, hints);
// 將BitMatrix渲染為BufferedImage(默認黑白)
BufferedImage barcodeImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
// 創(chuàng)建新圖像,包括條形碼和文本區(qū)域
int textHeight = 30; // 文本區(qū)域高度
BufferedImage combinedImage = new BufferedImage(width, height + textHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = combinedImage.createGraphics();
// 設置背景為白色
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height + textHeight);
// 繪制條形碼到新圖像的上部
g2d.drawImage(barcodeImage, 0, 0, null);
// 在條形碼下方添加文本
g2d.setColor(Color.BLACK);
g2d.setFont(new Font("Arial", Font.PLAIN, 20));
// 計算文本位置(居中)
FontMetrics metrics = g2d.getFontMetrics();
int textX = (width - metrics.stringWidth(textBelow)) / 2;
int textY = height + metrics.getHeight() / 2;
g2d.drawString(textBelow, textX, textY);
g2d.dispose(); // 釋放資源
return combinedImage;
}
}
2.3 代碼解釋
generateBarcode方法:接收條形碼數(shù)據(jù)、下方文本、寬度和高度參數(shù)。EncodeHintType.MARGIN:設置邊距,確保條碼周圍有空白,提高可讀性。Code128Writer.encode:生成BitMatrix,表示條碼的點陣。MatrixToImageWriter.toBufferedImage:將BitMatrix轉(zhuǎn)換為黑白圖像。- 文本添加:使用
Graphics2D在圖像下方繪制文本,計算居中位置確保美觀。 - 圖像處理:創(chuàng)建一個新圖像,包含條碼和文本區(qū)域,設置白色背景和黑色文本。
3. 二維碼生成實現(xiàn)
二維碼(QR Code)是一種二維矩陣碼,支持更多數(shù)據(jù)容量。我們將實現(xiàn)生成二維碼、更換中間logo、自定義顏色和樣式的功能。
3.1 二維碼生成原理
- 編碼類型:使用
QRCodeWriter生成QR碼。 - 添加Logo:在二維碼中心覆蓋一個logo圖像。
- 自定義顏色:通過自定義渲染過程設置前景色和背景色。
- 樣式:zxing支持基本樣式,如點形狀,但默認是方形點;我們可以通過渲染邏輯微調(diào)。
3.2 代碼實現(xiàn)
以下方法生成二維碼并添加自定義選項:
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class QRCodeGenerator {
/**
* 生成二維碼圖像,支持自定義logo、顏色和樣式。
*
* @param data 二維碼數(shù)據(jù)(如URL)
* @param logoPath logo圖像文件路徑(可選,null表示無logo)
* @param width 圖像寬度(像素)
* @param height 圖像高度(像素)
* @param foregroundColor 前景色(二維碼點顏色),如Color.BLACK
* @param backgroundColor 背景色,如Color.WHITE
* @return 生成的BufferedImage對象
* @throws WriterException 如果編碼失敗
* @throws IOException 如果logo文件讀取失敗
*/
public static BufferedImage generateQRCode(String data, String logoPath, int width, int height, Color foregroundColor, Color backgroundColor) throws WriterException, IOException {
// 設置編碼提示:糾錯級別(影響容錯率),邊距
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 高容錯級別,適合添加logo
hints.put(EncodeHintType.MARGIN, 4); // 設置邊距
// 創(chuàng)建QRCodeWriter實例并生成BitMatrix
QRCodeWriter writer = new QRCodeWriter();
BitMatrix bitMatrix = writer.encode(data, BarcodeFormat.QR_CODE, width, height, hints);
// 自定義渲染:創(chuàng)建彩色圖像
BufferedImage qrImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
qrImage.setRGB(x, y, bitMatrix.get(x, y) ? foregroundColor.getRGB() : backgroundColor.getRGB());
}
}
// 如果提供了logo路徑,添加logo到二維碼中心
if (logoPath != null && !logoPath.isEmpty()) {
BufferedImage logoImage = ImageIO.read(new File(logoPath));
qrImage = addLogoToQRCode(qrImage, logoImage);
}
return qrImage;
}
/**
* 在二維碼中心添加logo。
*
* @param qrImage 二維碼圖像
* @param logoImage logo圖像
* @return 添加logo后的新圖像
*/
private static BufferedImage addLogoToQRCode(BufferedImage qrImage, BufferedImage logoImage) {
int qrWidth = qrImage.getWidth();
int qrHeight = qrImage.getHeight();
// 調(diào)整logo為正方形
int size = Math.min(logoImage.getWidth(), logoImage.getHeight());
BufferedImage squareLogo = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = squareLogo.createGraphics();
g.drawImage(logoImage, 0, 0, size, size, (logoImage.getWidth() - size) / 2, (logoImage.getHeight() - size) / 2, (logoImage.getWidth() + size) / 2, (logoImage.getHeight() + size) / 2, null);
g.dispose();
// 縮放比例計算(保持Logo不超過二維碼尺寸的1/5)
int maxLogoSize = Math.min(qrWidth, qrHeight) / 5;
double scale = (double) maxLogoSize / size;
int logoWidth = (int) (size * scale);
int logoHeight = logoWidth; // 確保是正方形
// 縮放Logo
BufferedImage scaledLogo = new BufferedImage(logoWidth, logoHeight, BufferedImage.TYPE_INT_ARGB);
g = scaledLogo.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(squareLogo, 0, 0, logoWidth, logoHeight, null);
g.dispose();
// 計算 Logo 居中位置
int x = (qrWidth - logoWidth) / 2;
int y = (qrHeight - logoHeight) / 2;
// 創(chuàng)建新圖像并繪制二維碼和logo
BufferedImage combinedImage = new BufferedImage(qrWidth, qrHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = combinedImage.createGraphics();
g2d.drawImage(qrImage, 0, 0, null);
// 繪制logo(保持透明背景)
g2d.drawImage(scaledLogo, x, y, null);
g2d.dispose();
return combinedImage;
}
}
3.3 代碼解釋
generateQRCode方法:接收數(shù)據(jù)、logo路徑、尺寸、前景色和背景色參數(shù)。EncodeHintType.ERROR_CORRECTION:設置糾錯級別為H(最高),確保添加logo后仍可掃描。QRCodeWriter.encode:生成QR碼的BitMatrix。- 自定義渲染:通過遍歷
BitMatrix,設置每個像素的顏色,實現(xiàn)前景色和背景色自定義。 addLogoToQRCode方法:讀取logo文件,覆蓋到二維碼中心位置,保持透明背景。- 樣式說明:zxing默認使用方形點;如果需要圓點等樣式,可以在渲染時修改繪圖邏輯,但本實現(xiàn)聚焦核心功能。
4. 輔助方法:保存圖像
為了方便使用,我們添加一個保存圖像到文件的方法:
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
public class ImageUtils {
/**
* 保存BufferedImage到文件。
*
* @param image 圖像對象
* @param filePath 文件路徑(包括擴展名,如 "output.png")
* @throws IOException 如果保存失敗
*/
public static void saveImage(BufferedImage image, String filePath) throws IOException {
String format = filePath.substring(filePath.lastIndexOf(".") + 1);
ImageIO.write(image, format, new File(filePath));
}
}
5. 完整工具類
集成以上功能,創(chuàng)建一個完整的 BarcodeUtils 類,支持條形碼和二維碼生成,并包含保存功能。
import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.oned.Code128Writer;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class BarcodeUtils {
/**
* 生成條形碼圖像并添加下方文本。
*
* @param data 條形碼數(shù)據(jù)
* @param textBelow 下方文本
* @param width 寬度(像素)
* @param height 高度(像素),不包括文本區(qū)域
* @return BufferedImage對象
* @throws WriterException 編碼異常
*/
public static BufferedImage generateBarcodeWithText(String data, String textBelow, int width, int height) throws WriterException {
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.MARGIN, 10);
Code128Writer writer = new Code128Writer();
BitMatrix bitMatrix = writer.encode(data, BarcodeFormat.CODE_128, width, height, hints);
BufferedImage barcodeImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
int textHeight = 30;
BufferedImage combinedImage = new BufferedImage(width, height + textHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = combinedImage.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height + textHeight);
g2d.drawImage(barcodeImage, 0, 0, null);
g2d.setColor(Color.BLACK);
g2d.setFont(new Font("Arial", Font.PLAIN, 20));
FontMetrics metrics = g2d.getFontMetrics();
int textX = (width - metrics.stringWidth(textBelow)) / 2;
int textY = height + metrics.getHeight() / 2;
g2d.drawString(textBelow, textX, textY);
g2d.dispose();
return combinedImage;
}
/**
* 生成帶 Logo 的二維碼圖像
*
* @param data 二維碼內(nèi)容(如 URL、文本等)
* @param logoPath Logo 圖片路徑(支持 PNG 透明圖),若為 null 或空則不加 Logo
* @param width 二維碼寬度(像素)
* @param height 二維碼高度(像素)
* @param foregroundColor 二維碼前景色(通常是黑色)
* @param backgroundColor 二維碼背景色(通常是白色)
* @return 帶 Logo 的 BufferedImage 對象
* @throws WriterException 編碼錯誤
* @throws IOException 圖片讀取錯誤
*/
public static BufferedImage generateQRCodeWithLogo(String data,
String logoPath,
int width,
int height,
Color foregroundColor,
Color backgroundColor) throws WriterException, IOException {
// 設置二維碼編碼參數(shù)
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 高容錯率,支持覆蓋 Logo
hints.put(EncodeHintType.MARGIN, 2); // 邊距(默認是 4,這里可適當減小以留更多空間給 Logo)
// 生成二維碼 BitMatrix
QRCodeWriter writer = new QRCodeWriter();
BitMatrix bitMatrix = writer.encode(data, BarcodeFormat.QR_CODE, width, height, hints);
// 創(chuàng)建二維碼圖像(無 Logo 版本)
BufferedImage qrImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
qrImage.setRGB(x, y, bitMatrix.get(x, y) ? foregroundColor.getRGB() : backgroundColor.getRGB());
}
}
if (logoPath != null && !logoPath.isEmpty()) {
BufferedImage logoImage = ImageIO.read(new File(logoPath));
// 轉(zhuǎn)換為正方形
int size = Math.min(logoImage.getWidth(), logoImage.getHeight());
BufferedImage squareLogo = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = squareLogo.createGraphics();
g.drawImage(logoImage, 0, 0, size, size, (logoImage.getWidth() - size) / 2, (logoImage.getHeight() - size) / 2, (logoImage.getWidth() + size) / 2, (logoImage.getHeight() + size) / 2, null);
g.dispose();
// 縮放比例計算
int maxLogoSize = Math.min(width, height) / 5;
double scale = (double) maxLogoSize / size;
int logoWidth = (int) (size * scale);
int logoHeight = logoWidth; // 確保是正方形
// 縮放Logo
BufferedImage scaledLogo = new BufferedImage(logoWidth, logoHeight, BufferedImage.TYPE_INT_ARGB);
g = scaledLogo.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(squareLogo, 0, 0, logoWidth, logoHeight, null);
g.dispose();
// 計算 Logo 居中位置
int x = (width - logoWidth) / 2;
int y = (height - logoHeight) / 2;
// 合成最終圖像
BufferedImage combinedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
g = combinedImage.createGraphics();
g.setColor(backgroundColor);
g.fillRect(0, 0, width, height);
g.drawImage(qrImage, 0, 0, null);
g.drawImage(scaledLogo, x, y, null);
g.dispose();
return combinedImage;
}
return qrImage;
}
/**
* 保存圖像到文件。
*
* @param image 圖像對象
* @param filePath 文件路徑
* @throws IOException IO異常
*/
public static void saveImage(BufferedImage image, String filePath) throws IOException {
String format = filePath.substring(filePath.lastIndexOf(".") + 1);
ImageIO.write(image, format, new File(filePath));
}
}
5.1 類功能總結(jié)
generateBarcodeWithText:生成帶文本的條形碼。generateQRCodeWithLogo:生成自定義二維碼,支持logo、顏色。saveImage:保存圖像到文件。- 錯誤處理:拋出
WriterException和IOException,便于調(diào)用者處理異常。
6. 使用示例
以下是一個完整的示例,展示如何使用 BarcodeUtils 類生成條形碼和二維碼,并保存到文件。
import java.awt.*;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
// 生成條形碼示例
BufferedImage barcode = BarcodeUtils.generateBarcodeWithText("123456789", "產(chǎn)品ID: 123456", 300, 100);
BarcodeUtils.saveImage(barcode, "barcode.png");
System.out.println("條形碼生成成功!");
// 生成二維碼示例:無logo
BufferedImage qrCode1 = BarcodeUtils.generateQRCodeWithLogo("https://example.com", null, 300, 300, Color.BLUE, Color.WHITE);
BarcodeUtils.saveImage(qrCode1, "qrcode_blue.png");
// 生成二維碼示例:有l(wèi)ogo和自定義顏色
BufferedImage qrCode2 = BarcodeUtils.generateQRCodeWithLogo("https://example.com", "logo.png", 300, 300, Color.RED, Color.YELLOW);
BarcodeUtils.saveImage(qrCode2, "qrcode_logo.png");
System.out.println("二維碼生成成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
6.1 示例解釋
- 條形碼生成:數(shù)據(jù)為 "123456789",下方文本為 "產(chǎn)品ID: 123456",保存為
barcode.png。 - 二維碼無logo:數(shù)據(jù)為 URL,前景色藍色,背景色白色,保存為
qrcode_blue.png。 - 二維碼有l(wèi)ogo:添加
logo.png文件,前景色紅色,背景色黃色,保存為qrcode_logo.png。 - 錯誤處理:使用
try-catch捕獲異常,確保程序健壯性。
7. 實際應用建議
- 性能優(yōu)化:生成圖像可能消耗資源,建議在后臺線程執(zhí)行。
- 擴展功能:可添加更多條碼類型(如QR碼的
BarcodeFormat.QR_CODE可改為其他)。 - 安全性:處理用戶輸入時,驗證數(shù)據(jù)長度(例如QR碼最大容量約4KB)。
- 測試:使用JUnit測試不同輸入,確保生成圖像可被掃描器識別。
- 依賴更新:定期檢查
zxing庫更新,獲取新功能和安全修復。
總結(jié)
本文提供了完整的Java實現(xiàn),用于生成帶編號的條形碼和自定義二維碼(支持logo、顏色)。通過 zxing 庫,我們實現(xiàn)了高效、可定制的條碼生成功能。完整代碼可直接復制到項目中,依賴配置簡單,示例代碼便于測試??偞a和解釋超過3000字,確保實用性和可擴展性。如果您有更多需求(如其他條碼類型),可基于本代碼擴展。
以上就是Java生成條形碼和二維碼的完整指南的詳細內(nèi)容,更多關(guān)于Java生成條形碼和二維碼的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MySQL查詢字段實現(xiàn)字符串分割split功能的示例代碼
本文主要介紹了MySQL查詢字段實現(xiàn)字符串分割split功能的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01
Java xml數(shù)據(jù)格式返回實現(xiàn)操作
這篇文章主要介紹了Java xml數(shù)據(jù)格式返回實現(xiàn)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08

