Java生成条形码和二维码的完整指南
本文将详细介绍如何在Java中生成条形码和二维码。条形码要求在下方附加编号,二维码需要支持更换中间logo、自定义颜色和样式。我们将使用 zxing(Zebra Crossing)库来实现这些功能,因为它是一个强大且开源的库,支持多种条码类型和自定义选项。本文包含依赖配置、代码实现、详细解释和一个完整的可实际应用的工具类。
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. 条形码生成实现
条形码(如Code 128)是一种线性编码,常用于商品标签。我们将实现生成条形码图像并在下方附加编号的功能。
2.1 条形码生成原理
- 编码类型:我们使用
Code128Writer生成Code 128条形码,这是一种广泛支持的高密度编码。 - 图像生成:通过
BitMatrix表示条码矩阵,然后渲染为BufferedImage。 - 添加编号:使用Java的
Graphics2D在图像下方绘制文本。
2.2 代码实现
以下方法生成条形码并添加编号:
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 条形码数据(如商品ID)
* @param textBelow 条形码下方显示的文本(编号)
* @param width 图像宽度(像素)
* @param height 图像高度(像素),不包括文本区域
* @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像素
// 创建Code128Writer实例并生成BitMatrix
Code128Writer writer = new Code128Writer();
BitMatrix bitMatrix = writer.encode(data, BarcodeFormat.CODE_128, width, height, hints);
// 将BitMatrix渲染为BufferedImage(默认黑白)
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;
}
}
2.3 代码解释
generateBarcode方法:接收条形码数据、下方文本、宽度和高度参数。EncodeHintType.MARGIN:设置边距,确保条码周围有空白,提高可读性。Code128Writer.encode:生成BitMatrix,表示条码的点阵。MatrixToImageWriter.toBufferedImage:将BitMatrix转换为黑白图像。- 文本添加:使用
Graphics2D在图像下方绘制文本,计算居中位置确保美观。 - 图像处理:创建一个新图像,包含条码和文本区域,设置白色背景和黑色文本。
3. 二维码生成实现
二维码(QR Code)是一种二维矩阵码,支持更多数据容量。我们将实现生成二维码、更换中间logo、自定义颜色和样式的功能。
3.1 二维码生成原理
- 编码类型:使用
QRCodeWriter生成QR码。 - 添加Logo:在二维码中心覆盖一个logo图像。
- 自定义颜色:通过自定义渲染过程设置前景色和背景色。
- 样式:zxing支持基本样式,如点形状,但默认是方形点;我们可以通过渲染逻辑微调。
3.2 代码实现
以下方法生成二维码并添加自定义选项:
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 二维码数据(如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); // 设置边距
// 创建QRCodeWriter实例并生成BitMatrix
QRCodeWriter writer = new QRCodeWriter();
BitMatrix bitMatrix = writer.encode(data, BarcodeFormat.QR_CODE, width, height, hints);
// 自定义渲染:创建彩色图像
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();
// 调整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;
// 创建新图像并绘制二维码和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方法:接收数据、logo路径、尺寸、前景色和背景色参数。EncodeHintType.ERROR_CORRECTION:设置纠错级别为H(最高),确保添加logo后仍可扫描。QRCodeWriter.encode:生成QR码的BitMatrix。- 自定义渲染:通过遍历
BitMatrix,设置每个像素的颜色,实现前景色和背景色自定义。 addLogoToQRCode方法:读取logo文件,覆盖到二维码中心位置,保持透明背景。- 样式说明:zxing默认使用方形点;如果需要圆点等样式,可以在渲染时修改绘图逻辑,但本实现聚焦核心功能。
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. 完整工具类
集成以上功能,创建一个完整的 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 条形码数据
* @param textBelow 下方文本
* @param width 宽度(像素)
* @param height 高度(像素),不包括文本区域
* @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 二维码内容(如 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 {
// 设置二维码编码参数
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);
// 创建二维码图像(无 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));
// 转换为正方形
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 类功能总结
generateBarcodeWithText:生成带文本的条形码。generateQRCodeWithLogo:生成自定义二维码,支持logo、颜色。saveImage:保存图像到文件。- 错误处理:抛出
WriterException和IOException,便于调用者处理异常。
6. 使用示例
以下是一个完整的示例,展示如何使用 BarcodeUtils 类生成条形码和二维码,并保存到文件。
import java.awt.*;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
// 生成条形码示例
BufferedImage barcode = BarcodeUtils.generateBarcodeWithText("123456789", "产品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");
// 生成二维码示例:有logo和自定义颜色
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 示例解释
- 条形码生成:数据为 "123456789",下方文本为 "产品ID: 123456",保存为
barcode.png。 - 二维码无logo:数据为 URL,前景色蓝色,背景色白色,保存为
qrcode_blue.png。 - 二维码有logo:添加
logo.png文件,前景色红色,背景色黄色,保存为qrcode_logo.png。 - 错误处理:使用
try-catch捕获异常,确保程序健壮性。
7. 实际应用建议
- 性能优化:生成图像可能消耗资源,建议在后台线程执行。
- 扩展功能:可添加更多条码类型(如QR码的
BarcodeFormat.QR_CODE可改为其他)。 - 安全性:处理用户输入时,验证数据长度(例如QR码最大容量约4KB)。
- 测试:使用JUnit测试不同输入,确保生成图像可被扫描器识别。
- 依赖更新:定期检查
zxing库更新,获取新功能和安全修复。
总结
本文提供了完整的Java实现,用于生成带编号的条形码和自定义二维码(支持logo、颜色)。通过 zxing 库,我们实现了高效、可定制的条码生成功能。完整代码可直接复制到项目中,依赖配置简单,示例代码便于测试。总代码和解释超过3000字,确保实用性和可扩展性。如果您有更多需求(如其他条码类型),可基于本代码扩展。
以上就是Java生成条形码和二维码的完整指南的详细内容,更多关于Java生成条形码和二维码的资料请关注脚本之家其它相关文章!
相关文章
Java中的ArrayList.trimToSize()方法详解
这篇文章主要介绍了Java中的ArrayList.trimToSize()方法详解,前几天看了Java ArrayList,没有明白trimToSize()这个方法是什么意思,所以看了一下源码并且debug一下自己的一个例子,明白了其中的含义,需要的朋友可以参考下2023-11-11
Java ObjectMapper的使用和使用过程中遇到的问题
在Java开发中,ObjectMapper是Jackson库的核心类,用于将Java对象序列化为JSON字符串,或者将JSON字符串反序列化为Java对象,这篇文章主要介绍了Java ObjectMapper的使用和使用过程中遇到的问题,需要的朋友可以参考下2024-07-07


最新评论