本文目录导读:

我来为您提供一个完整的Java二维码生成和解析案例,使用ZXing库实现。
环境准备
Maven依赖
<dependencies>
<!-- ZXing 核心库 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.5.2</version>
</dependency>
<!-- ZXing JavaSE 扩展库 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.5.2</version>
</dependency>
</dependencies>
二维码生成工具类
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
/**
* 二维码生成工具类
*/
public class QRCodeUtil {
// 二维码颜色
private static final int BLACK = 0xFF000000;
// 二维码背景色
private static final int WHITE = 0xFFFFFFFF;
/**
* 生成二维码(返回BufferedImage)
*/
public static BufferedImage createQRCode(String content, int width, int height)
throws Exception {
Map<EncodeHintType, Object> hints = new HashMap<>();
// 设置编码类型
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
// 设置纠错等级(L-低, M-中, Q-较高, H-高)
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
// 设置边距(白边)
hints.put(EncodeHintType.MARGIN, 1);
// 生成二维码矩阵
BitMatrix bitMatrix = new MultiFormatWriter()
.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
// 创建图片
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// 绘制二维码
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, bitMatrix.get(x, y) ? BLACK : WHITE);
}
}
return image;
}
/**
* 生成带Logo的二维码
*/
public static BufferedImage createQRCodeWithLogo(String content, int width,
int height, BufferedImage logoImage) throws Exception {
// 先生成普通二维码
BufferedImage qrImage = createQRCode(content, width, height);
if (logoImage != null) {
// 计算Logo大小(约为二维码的1/5)
int logoSize = width / 5;
// 创建Graphics2D对象
Graphics2D g2d = qrImage.createGraphics();
// 设置Logo位置
int x = (width - logoSize) / 2;
int y = (height - logoSize) / 2;
// 绘制圆角背景
RoundRectangle2D roundedRect = new RoundRectangle2D.Float(
x - 2, y - 2, logoSize + 4, logoSize + 4, 20, 20);
g2d.setColor(Color.WHITE);
g2d.fill(roundedRect);
// 设置抗锯齿
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// 绘制Logo
Image logo = logoImage.getScaledInstance(logoSize, logoSize,
Image.SCALE_SMOOTH);
g2d.drawImage(logo, x, y, null);
// 设置边框
g2d.setColor(Color.LIGHT_GRAY);
g2d.setStroke(new BasicStroke(2));
g2d.draw(roundedRect);
g2d.dispose();
}
return qrImage;
}
/**
* 生成二维码到文件
*/
public static void createQRCodeToFile(String content, int width, int height,
File outputFile) throws Exception {
BufferedImage image = createQRCode(content, width, height);
// 根据文件后缀判断格式
String fileName = outputFile.getName();
String format = fileName.substring(fileName.lastIndexOf(".") + 1);
ImageIO.write(image, format, outputFile);
}
/**
* 生成二维码到输出流
*/
public static void createQRCodeToStream(String content, int width, int height,
OutputStream outputStream, String format) throws Exception {
BufferedImage image = createQRCode(content, width, height);
ImageIO.write(image, format, outputStream);
}
/**
* 生成带Logo的二维码到文件
*/
public static void createQRCodeWithLogoToFile(String content, int width,
int height, File logoFile, File outputFile) throws Exception {
BufferedImage logoImage = ImageIO.read(logoFile);
BufferedImage image = createQRCodeWithLogo(content, width, height, logoImage);
String fileName = outputFile.getName();
String format = fileName.substring(fileName.lastIndexOf(".") + 1);
ImageIO.write(image, format, outputFile);
}
}
二维码解析工具类
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
/**
* 二维码解析工具类
*/
public class QRCodeParser {
/**
* 解析图片中的二维码
*/
public static String parseQRCode(BufferedImage image) throws Exception {
if (image == null) {
throw new IllegalArgumentException("图片不能为空");
}
// 转换图像数据
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
// 设置解码提示
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
// 解码二维码
MultiFormatReader reader = new MultiFormatReader();
Result result = reader.decode(bitmap, hints);
return result.getText();
}
/**
* 解析文件中的二维码
*/
public static String parseQRCodeFromFile(File file) throws Exception {
BufferedImage image = ImageIO.read(file);
return parseQRCode(image);
}
/**
* 从输入流解析二维码
*/
public static String parseQRCodeFromStream(InputStream inputStream)
throws Exception {
BufferedImage image = ImageIO.read(inputStream);
return parseQRCode(image);
}
/**
* 解析二维码,返回详细结果
*/
public static Result parseQRCodeDetail(BufferedImage image) throws Exception {
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
MultiFormatReader reader = new MultiFormatReader();
return reader.decode(bitmap, hints);
}
}
测试用例
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
/**
* 测试类
*/
public class QRCodeTest {
public static void main(String[] args) {
try {
// 测试1:生成简单二维码
String content = "https://www.example.com";
File qrFile = new File("qr_code.png");
QRCodeUtil.createQRCodeToFile(content, 300, 300, qrFile);
// 解析二维码
String parsedContent = QRCodeParser.parseQRCodeFromFile(qrFile);
System.out.println("解析结果: " + parsedContent);
System.out.println("验证成功: " + content.equals(parsedContent));
// 测试2:生成带Logo的二维码
// 创建简单的Logo(纯色图片)
BufferedImage logo = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = logo.createGraphics();
g2d.setColor(Color.RED);
g2d.fillOval(10, 10, 80, 80);
g2d.setColor(Color.WHITE);
g2d.setFont(new Font("Arial", Font.BOLD, 30));
g2d.drawString("LOGO", 15, 60);
g2d.dispose();
File logoFile = new File("qr_code_with_logo.png");
QRCodeUtil.createQRCodeWithLogoToFile(content, 300, 300, logo, logoFile);
// 解析带Logo的二维码
BufferedImage qrImage = ImageIO.read(logoFile);
String parsedLogoContent = QRCodeParser.parseQRCode(qrImage);
System.out.println("带Logo二维码解析结果: " + parsedLogoContent);
// 测试3:不同大小的二维码
File smallQR = new File("qr_code_small.png");
QRCodeUtil.createQRCodeToFile("Hello World", 150, 150, smallQR);
// 测试4:编码中文内容
File chineseQR = new File("qr_code_chinese.png");
String chineseContent = "你好,世界!";
QRCodeUtil.createQRCodeToFile(chineseContent, 200, 200, chineseQR);
String parsedChinese = QRCodeParser.parseQRCodeFromFile(chineseQR);
System.out.println("中文内容解析: " + parsedChinese);
} catch (Exception e) {
e.printStackTrace();
}
}
}
简单的生成界面示例(Swing)
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
/**
* 简单的二维码生成界面
*/
public class QRCodeUI extends JFrame {
private JTextField contentField;
private JTextField sizeField;
private JButton generateBtn;
private JLabel qrLabel;
public QRCodeUI() {
setTitle("二维码生成器");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout(10, 10));
// 创建输入面板
JPanel inputPanel = new JPanel(new GridLayout(3, 2, 10, 10));
inputPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
inputPanel.add(new JLabel("二维码内容:"));
contentField = new JTextField();
inputPanel.add(contentField);
inputPanel.add(new JLabel("二维码大小(px):"));
sizeField = new JTextField("300");
inputPanel.add(sizeField);
generateBtn = new JButton("生成二维码");
inputPanel.add(generateBtn);
inputPanel.add(new JLabel(""));
add(inputPanel, BorderLayout.NORTH);
// 创建显示区域
qrLabel = new JLabel("", SwingConstants.CENTER);
qrLabel.setBorder(BorderFactory.createLineBorder(Color.GRAY));
add(qrLabel, BorderLayout.CENTER);
// 添加生成按钮事件
generateBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
generateQRCode();
}
});
setSize(500, 500);
setLocationRelativeTo(null);
setVisible(true);
}
private void generateQRCode() {
try {
String content = contentField.getText();
int size = Integer.parseInt(sizeField.getText());
if (content.isEmpty()) {
JOptionPane.showMessageDialog(this, "请输入二维码内容!");
return;
}
// 生成二维码
BufferedImage qrImage = QRCodeUtil.createQRCode(content, size, size);
// 显示二维码
ImageIcon icon = new ImageIcon(qrImage);
qrLabel.setIcon(icon);
// 保存到文件
JFileChooser fileChooser = new JFileChooser();
fileChooser.setSelectedFile(new File("qr_code.png"));
if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
File outputFile = fileChooser.getSelectedFile();
QRCodeUtil.createQRCodeToFile(content, size, size, outputFile);
JOptionPane.showMessageDialog(this, "二维码保存成功!");
}
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(this, "请输入有效的大小!");
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(this, "生成失败: " + ex.getMessage());
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new QRCodeUI();
}
});
}
}
高级功能示例
import com.google.zxing.common.BitMatrix;
/**
* 高级功能示例
*/
public class QRCodeAdvanced {
/**
* 生成彩色二维码
*/
public static BufferedImage createColoredQRCode(String content, int width,
int height, int foregroundColor, int backgroundColor) throws Exception {
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
BitMatrix bitMatrix = new MultiFormatWriter()
.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, bitMatrix.get(x, y) ? foregroundColor : backgroundColor);
}
}
return image;
}
/**
* 生成带渐变效果的二维码
*/
public static BufferedImage createGradientQRCode(String content, int width,
int height, Color startColor, Color endColor) throws Exception {
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
BitMatrix bitMatrix = new MultiFormatWriter()
.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// 创建渐变
GradientPaint gradient = new GradientPaint(
0, 0, startColor,
width, height, endColor);
Graphics2D g2d = image.createGraphics();
g2d.setPaint(Color.WHITE);
g2d.fillRect(0, 0, width, height);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (bitMatrix.get(x, y)) {
// 根据位置计算颜色
float ratio = (float)(x + y) / (width + height);
Color pixelColor = interpolateColor(startColor, endColor, ratio);
image.setRGB(x, y, pixelColor.getRGB());
}
}
}
g2d.dispose();
return image;
}
private static Color interpolateColor(Color c1, Color c2, float ratio) {
int r = (int)(c1.getRed() * (1 - ratio) + c2.getRed() * ratio);
int g = (int)(c1.getGreen() * (1 - ratio) + c2.getGreen() * ratio);
int b = (int)(c1.getBlue() * (1 - ratio) + c2.getBlue() * ratio);
return new Color(r, g, b);
}
}
使用说明
-
基础使用:
- 使用
QRCodeUtil.createQRCodeToFile()生成二维码文件 - 使用
QRCodeParser.parseQRCodeFromFile()解析二维码
- 使用
-
功能特性:
- 支持自定义大小和颜色
- 支持添加Logo
- 支持中英文内容
- 可设置不同的纠错级别
-
常见应用场景:
- 商品信息链接
- 支付二维码
- 身份验证
- 活动宣传
- 电子票务
这个案例提供了完整的二维码解决方案,您可以根据实际需求进行调整和扩展。