Java条码与二维码生成技术详解
一、技术选型分析
1.1 条码生成方案
Barbecue是最成熟的Java条码库,支持:
- Code 128
- EAN-13/UPC-A
- USPS Inteligent Mail
- 等12种工业标准格式
1.2 二维码方案对比
库名称 | 维护状态 | 复杂度 | 功能扩展性 |
---|---|---|---|
ZXing | ★★★★☆ | 较高 | 强 |
QRGen | ★★★☆☆ | 简单 | 一般 |
BoofCV | ★★☆☆☆ | 复杂 | 强 |
二、环境准备
2.1 Maven依赖
<!-- 条码生成 -->
<dependency>
<groupId>net.sf.barbecue</groupId>
<artifactId>barbecue</artifactId>
<version>1.5-beta1</version>
</dependency>
<!-- 二维码核心库 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.1</version>
</dependency>
<!-- 二维码图形生成 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.4.1</version>
</dependency>
<!-- QRGen简化封装 -->
<dependency>
<groupId>net.glxn</groupId>
<artifactId>qrgen</artifactId>
<version>2.0</version>
</dependency>
三、条码生成实战
3.1 Code 128基础生成
public static void generateCode128(String data, File outputFile)
throws BarcodeException, IOException {
Barcode barcode = BarcodeFactory.createCode128(data);
barcode.setResolution(300); // 设置DPI
// 设置尺寸策略
barcode.setBarWidth(2);
barcode.setBarHeight(50);
// 添加文本标签
barcode.setDrawingText(true);
barcode.setFont(new Font("Arial", Font.PLAIN, 12));
BarcodeImageHandler.savePNG(barcode, outputFile);
}
3.2 物流条码生成示例(Inteligent Mail)
public static void generateInteligentMail(String routingCode, File output)
throws Exception {
IntelligentMailBarcode imb = new IntelligentMailBarcode(
routingCode, // 路由编码
"9405511042", // 跟踪号
"1234" // 服务类型代码
);
imb.setHumanReadableTextPosition(Barcode.HUMAN_READABLE_BOTTOM);
imb.setBarHeight(40);
BufferedImage image = new BufferedImage(
300, 60, BufferedImage.TYPE_BYTE_BINARY);
imb.draw(image.createGraphics(), new Point(10, 10));
ImageIO.write(image, "PNG", output);
}
四、二维码高级应用
4.1 ZXing基础生成
public static void generateQRWithZXing(String content, int width, int height, File file)
throws WriterException, IOException {
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 30%容错
hints.put(EncodeHintType.MARGIN, 2); // 边距
BitMatrix matrix = new MultiFormatWriter()
.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
MatrixToImageWriter.writeToPath(
matrix,
"PNG",
file.toPath(),
new MatrixToImageConfig(0xFF000000, 0xFFFFFFFF) // 自定义颜色
);
}
4.2 带Logo的复杂二维码
public static void generateQRWithLogo(String content, File logoFile, File output)
throws Exception {
// 生成基础二维码
BufferedImage qrImage = MatrixToImageWriter.toBufferedImage(
new QRCodeWriter().encode(
content,
BarcodeFormat.QR_CODE,
400, 400,
Collections.singletonMap(EncodeHintType.MARGIN, 1)
)
);
// 添加Logo
BufferedImage logo = ImageIO.read(logoFile);
Graphics2D graphics = qrImage.createGraphics();
int logoSize = qrImage.getWidth() / 5;
int x = (qrImage.getWidth() - logoSize) / 2;
int y = (qrImage.getHeight() - logoSize) / 2;
graphics.drawImage(logo, x, y, logoSize, logoSize, null);
// 添加抗锯齿效果
graphics.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
);
graphics.dispose();
ImageIO.write(qrImage, "PNG", output);
}
五、性能优化建议
- 对象复用:频繁生成时复用BarcodeFactory实例
- 异步生成:使用CompletableFuture实现并行生成
- 缓存策略:对固定内容条码进行内存缓存
- 分辨率控制:根据输出介质动态调整DPI
- 屏幕显示:72-96 DPI
- 打印输出:300+ DPI
六、异常处理最佳实践
public void safeGenerateQR(String content) {
try {
// 生成逻辑...
} catch (WriterException e) {
logger.error("内容编码失败: {}", e.getMessage());
if (e.getMessage().contains("Contents length")) {
throw new IllegalArgumentException("输入内容过长");
}
} catch (IOException e) {
logger.error("IO异常: {}", e.getMessage());
throw new RuntimeException("文件保存失败");
} finally {
// 清理临时资源
}
}
七、扩展功能实现
7.1 生成彩色二维码
public static void generateColorQR() throws Exception {
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
BitMatrix matrix = new QRCodeWriter()
.encode("https://example.com", BarcodeFormat.QR_CODE, 300, 300, hints);
BufferedImage image = new BufferedImage(
300, 300, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < matrix.getWidth(); x++) {
for (int y = 0; y < matrix.getHeight(); y++) {
image.setRGB(x, y,
matrix.get(x, y) ?
0xFF0099FF : // 蓝色数据点
0xFFFFFFFF); // 白色背景
}
}
}
7.2 生成动态GIF二维码
public static void generateAnimatedQR() throws Exception {
GifSequenceWriter gifWriter = new GifSequenceWriter(
new FileOutputStream("animated_qr.gif"),
BufferedImage.TYPE_INT_RGB,
500, // 帧间隔
true
);
for (int i = 0; i < 10; i++) {
BufferedImage frame = MatrixToImageWriter.toBufferedImage(
new QRCodeWriter().encode(
"Frame " + i,
BarcodeFormat.QR_CODE,
200, 200
)
);
gifWriter.writeToSequence(frame);
}
gifWriter.close();
}
八、行业应用案例
- 医疗行业:生成包含患者ID的腕带条码
- 零售系统:商品二维码集成防伪信息
- 物流追踪:复合码(Code128)