杰瑞科技汇

java zxing二维码生成

下面我将为你提供一个详细的指南,包括:

  1. 环境准备 (Maven/Gradle 依赖)
  2. 最简单的生成代码示例
  3. 进阶功能 (添加 Logo、设置二维码大小、纠错级别等)
  4. 完整的、可运行的示例代码

环境准备

你需要在你的 Java 项目中添加 ZXing 的核心库依赖,推荐使用 Maven 或 Gradle 来管理依赖。

使用 Maven

在你的 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.5.2</version> <!-- 建议使用较新版本 -->
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.5.2</version> <!-- Java SE 实现,包含 MatrixToImageWriter -->
</dependency>

使用 Gradle

在你的 build.gradle 文件中添加以下依赖:

implementation 'com.google.zxing:core:3.5.2'
implementation 'com.google.zxing:javase:3.5.2'

最简单的生成代码示例

这个示例将生成一个包含文本 "Hello, ZXing!" 的二维码,并将其保存为 PNG 图片文件。

核心步骤:

  1. 创建 BitMatrix 对象,它代表了二维码的黑白像素矩阵。
  2. 使用 MatrixToImageWriterBitMatrix 写入到图片文件中。
import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
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.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
public class SimpleQRCodeGenerator {
    public static void main(String[] args) {
        String text = "Hello, ZXing! 这是一个简单的二维码示例。"; // 要编码的内容
        int width = 300; // 二维码宽度
        int height = 300; // 二维码高度
        String format = "png"; // 图片格式
        Path path = Paths.get("simple-qrcode.png"); // 输出文件路径
        try {
            // 1. 定义二维码的参数
            Map<EncodeHintType, Object> hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 设置字符编码
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 设置纠错级别
            // 2. 使用 QRCodeWriter 生成 BitMatrix
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints);
            // 3. 将 BitMatrix 写入到文件
            MatrixToImageWriter.writeToPath(bitMatrix, format, path);
            System.out.println("二维码图片已成功生成并保存到: " + path);
        } catch (WriterException e) {
            System.err.println("生成二维码时发生错误: " + e.getMessage());
        } catch (IOException e) {
            System.err.println("写入文件时发生错误: " + e.getMessage());
        }
    }
}

运行这段代码后,你会在项目根目录下找到一个名为 simple-qrcode.png 的文件,用手机扫码即可看到 "Hello, ZXing!" 的内容。


进阶功能

1 添加 Logo 图片

在二维码中心添加一个 Logo 图片,可以让二维码更具个性化。

思路:

  1. 先生成原始的二维码图片。
  2. 读取你的 Logo 图片。
  3. 将 Logo 图片绘制到二维码图片的中心位置。
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class QRCodeWithLogo {
    public static void main(String[] args) throws IOException, WriterException {
        // 1. 生成原始二维码
        String text = "https://www.google.com";
        int qrCodeWidth = 300;
        int qrCodeHeight = 300;
        String qrCodeFormat = "png";
        Path qrCodePath = Paths.get("qrcode-with-logo.png");
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, qrCodeWidth, qrCodeHeight, hints);
        // 生成二维码 BufferedImage
        BufferedImage qrCodeImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
        // 2. 读取 Logo 图片
        File logoFile = new File("path/to/your/logo.png"); // 替换为你的Logo路径
        if (!logoFile.exists()) {
            System.err.println("Logo文件不存在: " + logoFile.getAbsolutePath());
            return;
        }
        BufferedImage logoImage = ImageIO.read(logoFile);
        // 3. 将 Logo 绘制到二维码上
        // 计算Logo的大小,通常为二维码的1/5到1/4
        int logoWidth = qrCodeWidth / 5;
        int logoHeight = qrCodeHeight / 5;
        // 计算Logo的位置(居中)
        int x = (qrCodeWidth - logoWidth) / 2;
        int y = (qrCodeHeight - logoHeight) / 2;
        // 创建一个新的空白图片,用于合并
        BufferedImage combined = new BufferedImage(qrCodeWidth, qrCodeHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = (Graphics2D) combined.getGraphics();
        // 先绘制二维码
        g.drawImage(qrCodeImage, 0, 0, null);
        // 再绘制Logo
        g.drawImage(logoImage, x, y, logoWidth, logoHeight, null);
        // 4. 保存合并后的图片
        ImageIO.write(combined, qrCodeFormat, qrCodePath.toFile());
        System.out.println("带Logo的二维码已生成: " + qrCodePath);
    }
}

2 设置二维码大小和纠错级别

在第一个示例中我们已经展示了如何设置这些参数,这里再详细说明一下:

  • 宽度和高度: 直接在 qrCodeWriter.encode() 方法中指定。
  • 纠错级别 (ErrorCorrectionLevel):
    • L (Low): 约7%的纠错能力。
    • M (Medium): 约15%的纠错能力,这是默认级别。
    • Q (Quartile): 约25%的纠错能力。
    • H (High): 约30%的纠错能力。
    • 建议: 对于包含 Logo 的二维码,建议使用 HQ 级别,因为 Logo 会覆盖部分二维码区域,高纠错能力可以确保即使部分信息被遮挡,二维码仍然可以被正确识别。
  • 字符编码 (CHARACTER_SET):
    • 必须设置为 "UTF-8",这样才能正确处理中文、表情符号等非ASCII字符。
// 设置 hints
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 使用高纠错级别
// 可以设置二维码的边距
hints.put(EncodeHintType.MARGIN, 2); // 边距,值为1-4

完整的、可运行的示例代码

下面是一个结合了所有功能的完整类,你可以直接复制、修改并运行。

准备工作:

  1. 创建一个 Java 项目,并添加 Maven/Gradle 依赖。
  2. 在项目根目录下放置一个名为 logo.png 的图片文件(或者修改代码中的路径)。

AdvancedQRCodeGenerator.java

import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
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.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class AdvancedQRCodeGenerator {
    public static void main(String[] args) {
        // --- 配置参数 ---
        String content = "这是一个包含Logo的二维码,测试中文和纠错能力。"; // 要编码的内容
        int width = 400;
        int height = 400;
        String format = "png";
        Path outputPath = Paths.get("advanced-qrcode.png");
        String logoPath = "logo.png"; // Logo图片路径
        try {
            // 1. 生成二维码 BitMatrix
            BitMatrix bitMatrix = generateQRCode(content, width, height);
            // 2. 生成二维码 BufferedImage
            BufferedImage qrCodeImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
            // 3. 如果Logo存在,则添加Logo
            File logoFile = new File(logoPath);
            if (logoFile.exists()) {
                BufferedImage logoImage = ImageIO.read(logoFile);
                BufferedImage combinedImage = addLogoToQRCode(qrCodeImage, logoImage);
                // 4. 保存带Logo的图片
                ImageIO.write(combinedImage, format, outputPath.toFile());
            } else {
                // 如果没有Logo,直接保存原始二维码
                MatrixToImageWriter.writeToPath(bitMatrix, format, outputPath);
            }
            System.out.println("二维码生成成功!文件路径: " + outputPath);
        } catch (WriterException e) {
            System.err.println("二维码编码失败: " + e.getMessage());
        } catch (IOException e) {
            System.err.println("图片读写失败: " + e.getMessage());
        }
    }
    /**
     * 生成二维码的 BitMatrix
     */
    private static BitMatrix generateQRCode(String content, int width, int height) throws WriterException {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        // 设置二维码参数
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 高纠错
        hints.put(EncodeHintType.MARGIN, 2); // 设置边距
        return qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
    }
    /**
     * 将Logo添加到二维码中心
     */
    private static BufferedImage addLogoToQRCode(BufferedImage qrCodeImage, BufferedImage logoImage) {
        // 计算Logo大小,不超过二维码的1/5
        int logoWidth = qrCodeImage.getWidth() / 5;
        int logoHeight = qrCodeImage.getHeight() / 5;
        // 保持Logo原始宽高比
        if (logoImage.getWidth() > logoImage.getHeight()) {
            logoHeight = (int) (logoHeight * (double) logoImage.getHeight() / logoImage.getWidth());
        } else {
            logoWidth = (int) (logoWidth * (double) logoImage.getWidth() / logoImage.getHeight());
        }
        // 计算Logo位置(居中)
        int x = (qrCodeImage.getWidth() - logoWidth) / 2;
        int y = (qrCodeImage.getHeight() - logoHeight) / 2;
        // 创建一个新的空白图片用于合并
        BufferedImage combined = new BufferedImage(qrCodeImage.getWidth(), qrCodeImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = (Graphics2D) combined.getGraphics();
        // 先绘制二维码
        g.drawImage(qrCodeImage, 0, 0, null);
        // 设置抗锯齿,使Logo更平滑
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        // 再绘制Logo
        g.drawImage(logoImage, x, y, logoWidth, logoHeight, null);
        return combined;
    }
}

这个完整示例将帮助你快速上手,并根据需要灵活调整参数,祝你编码愉快!

分享:
扫描分享到社交APP
上一篇
下一篇