| 維度 | ZXing (Zebra Crossing) | QRGen | Swetake QRCode | Barcode4j |
|---|---|---|---|---|
| Maven 坐標 | com.google.zxing:core:3.5.1com.google.zxing:javase:3.5.1 | net.glxn:qrgen:2.6.0 | jp.sourceforge.qrcode:qrcode:1.0 | net.sf.barcode4j:barcode4j:2.1 |
| 核心定位 | 多格式 1D/2D 條碼/二維碼**工業標準庫** | ZXing 簡易封裝,**極簡 API** | 純 Java QR Code 實現,**日系老牌** | 條碼為主,**DataMatrix PDF417** 專長 |
| 支持格式 | QR Code, DataMatrix, PDF417, Aztec, UPC/EAN, Code128, Code39 等 20+ | 同 ZXing (僅封裝生成) | 僅 QR Code (JIS X 0510 / ISO 18004) | DataMatrix, PDF417, QR Code, UPC/EAN, Code128 等 |
| 解析能力 | **全格式解析**、多角度、旋轉、鏡像、模糊識別 | 不支持解析 | 支持解析 (需額外 qrcode.jar) | 支持 DataMatrix/PDF417/QR Code 解析 |
| API 風格 | 底層、靈活、需組裝 Hint/Writer/Reader | 鏈式調用 QRCode.from("txt").to(ImageType.PNG).writeTo(...) | 傳統 JavaBean 風格 Qrcode qrcode = new Qrcode(); qrcode.calQrcode() | 基於 Canvas/Provider 模式,適合報表集成 |
| 依賴體積 | core 300KB + javase 200KB | ~50KB (傳遞依賴 ZXing) | ~50KB (單 JAR 無依賴) | ~500KB (含 Batik SVG 依賴) |
| 維護狀態 | 活躍 (Google 維護、社區活躍、定期發布) | 低維護 (依賴 ZXing 版本) | 停止維護 (最後更新 2013) | 低維護 (Apache 項目、近年少更新) |
| 性能 | 高 (優化矩陣運算、原生圖像輸出) | 同 ZXing | 中 (純 Java 繪圖、無優化) | 中 (側重矢量輸出 SVG/EPS) |
| 輸出格式 | BufferedImage → PNG/JPG/GIF/BMP (ImageIO) | File/OutputStream/ByteArray/Base64 | BufferedImage → PNG (ImageIO) | SVG、EPS、PDF、PNG、JPEG、AWT (矢量優勢) |
| 中文支持 | 完美 (UTF-8 Hint) | 完美 | 支持 (需指定編碼) | 支持 |
| Logo 嵌入 | 需自行繪圖合成 | 內建 .withLogo() (簡單) | 需自行繪圖 | 需自行繪圖 |
| 適用場景 | 生產首選:生成+解析、多格式、高性能、長期維護 | 快速原型、僅生成、不想寫樣板代碼 | 極簡依賴環境、舊項目維護、純 QR Code | **報表/打印/矢量輸出**、DataMatrix/PDF417 專業場景 |
Map hints = Map.of(
EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M,
EncodeHintType.CHARACTER_SET, "UTF-8",
EncodeHintType.MARGIN, 2
);
BitMatrix matrix = new MultiFormatWriter()
.encode("Hello 世界", BarcodeFormat.QR_CODE, 300, 300, hints);
BufferedImage image = MatrixToImageWriter.toBufferedImage(matrix);
ImageIO.write(image, "PNG", new File("zxing.png"));
QRCode.from("Hello 世界")
.withSize(300, 300)
.withErrorCorrection(ErrorCorrectionLevel.M)
.withCharset("UTF-8")
.to(ImageType.PNG)
.writeTo(new File("qrgen.png"));
// 帶 Logo
QRCode.from("Hello 世界")
.withLogo(new File("logo.png")) // 內建 Logo 支持
.to(ImageType.PNG)
.writeTo(new File("qrgen-logo.png"));
Qrcode qrcode = new Qrcode();
qrcode.setQrcodeErrorCorrect('M'); // L/M/Q/H
qrcode.setQrcodeEncodeMode('B'); // N/A/B/K
qrcode.setQrcodeVersion(7); // 1-40 (自動版本設 0)
byte[] data = "Hello 世界".getBytes("GB2312"); // 注意編碼
boolean[][] matrix = qrcode.calQrcode(data);
BufferedImage img = new BufferedImage(140, 140, BufferedImage.TYPE_INT_RGB);
Graphics2D g = img.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, 140, 140);
g.setColor(Color.BLACK);
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix.length; j++) {
if (matrix[j][i]) g.fillRect(j * 3 + 2, i * 3 + 2, 3, 3);
}
}
ImageIO.write(img, "PNG", new File("swetake.png"));
QRCodeBean bean = new QRCodeBean();
bean.setModuleWidth(UnitConv.in2mm(1.0f / 72)); // 模塊寬度
bean.setMsg("Hello 世界");
bean.setErrorCorrectionLevel(ErrorCorrectionLevel.M);
CanvasProvider canvas = new SVGCanvasProvider(
false, 0, new FileOutputStream("barcode4j.svg"));
QRCodeLogicImpl logic = new QRCodeLogicImpl();
logic.generateBarcode(canvas, bean);
canvas.finish();
需要解析/掃描? ──Yes──► ZXing (唯一完整支持生成+解析)
否
需要 SVG/EPS/PDF 矢量輸出/專業打印? ──Yes──► Barcode4j
否
僅生成 QR Code、極簡依賴、不想寫 Hint? ──Yes──► QRGen
否
純 QR Code、舊項目、無法引入 ZXing? ──Yes──► Swetake (不推薦新項目)
否
默認選 ZXing (功能最全、性能最好、社區最活躍)
參考文章 236984 的 QrCodeGenerator / QrCodeParser 封裝,提供:
| 坑點 | 影響庫 | 解決 |
|---|---|---|
| Swetake 生成中文亂碼 | Swetake | 強制 getBytes("GB2312") 或升級 ZXing |
| ZXing 解析 NotFoundException | ZXing | TRY_HARDER=true、多角度旋轉、圖像預處理(銳化/二值化) |
| Barcode4j SVG 輸出中文方塊 | Barcode4j | 配置字體映射 font-family="SimSun"、嵌入字體 |
| QRGen Logo 遮擋導致不可識別 | QRGen | 縮小 Logo 比例 ≤ 0.2、留白邊距、提高糾錯級別至 Q/H |
| 依賴衝突: 多個 ZXing 版本共存 | 所有 | mvn dependency:tree 排查、<exclusion> 統一版本 |
**新項目無腦選 ZXing** —— 功能最全、性能最強、社區最活、解析生成一站式。QRGen 適合快速寫 Demo/測試;Barcode4j 專攻矢量輸出/報表打印;Swetake 已進入博物館,**嚴禁新項目引入**。封裝統一工具類,業務層零感知切換實現,才是架構師的正確姿勢。