首页 > 编程开发 > Java    日期:2026-07-03 / 浏览

所需依赖

<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.5.3</version>
</dependency>

生成一个带颜色的图片

  • 参数一:可以是网址或者文本信息
  • 参数二:图片尺寸
public static BufferedImage generate(String content, int size) {
    // 创建参数容器
    Map<EncodeHintType, Object> hints = new HashMap<>();
    // 设置容错等级(允许 logo 覆盖),就是高,扫一半也可以扫出来
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
    // 设置白边(0 = 无白边)
    hints.put(EncodeHintType.MARGIN, 0);
    // ZXing 的编码器工厂
    // 参数一:内容,参数二:生成的类型是二维码
    // 参数三和四:宽高,参数五:规则配置。
    BitMatrix matrix;
    try {
        matrix = new MultiFormatWriter().encode(
                content, BarcodeFormat.QR_CODE, size, size, hints
        );
    } catch (WriterException e) {
        throw new RuntimeException(e);
    }

    int width = matrix.getWidth();
    int height = matrix.getHeight();

    // 创建图片画布,参数三是:带颜色的画布RGB
    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, matrix.get(x, y) ? 0x000000 : 0xFFFFFF);
        }
    }
    return image;
}

增加logo

public static BufferedImage addLogo(BufferedImage qr, String logoPath) throws Exception {
    // 读取 logo 图片
    BufferedImage logo = ImageIO.read(new File(logoPath));
    // 根据二维码大小,动态计算 logo 要占多少空间
    int qrSize = qr.getWidth();
    // 除以 5,logo 占二维码的 1/5
    int logoSize = qrSize / 5;
    // 1px像素边框
    int border = 1;
    int boxSize = logoSize + border * 2;

    // 把原始 logo 压缩/缩放成 logoSize × logoSize 的图片
    // 图片缩小 / 放大
    // SCALE_SMOOTH = 平滑缩放、清晰、速度稍慢
    Image scaledLogo = logo.getScaledInstance(
            logoSize, logoSize,
            Image.SCALE_SMOOTH);

    // 开启高质量模式
    // 绘画器
    Graphics2D g = qr.createGraphics();
    // KEY_ANTIALIASING = 抗锯齿
    // VALUE_ANTIALIAS_ON = 开启
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    // KEY_RENDERING = 渲染策略
    // VALUE_RENDER_QUALITY = 高质量模式
    g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

    // 把 logo 放到二维码正中间
    int x = (qrSize - logoSize) / 2;
    int y = (qrSize - logoSize) / 2;

    // 1. 先画像素边框(矩形框)
    g.setColor(Color.BLACK); // 你也可以换成品牌色
    g.fillRect(x, y, boxSize, boxSize);

    // 2. 再在中间画 logo(留1px边框)
    g.drawImage(scaledLogo, x + border, y + border, null);
    g.dispose();
    return qr;
}

知识扩展

在 Java 中生成二维码,目前最主流的解决方案是使用 Google 开源的 ZXing(Zebra Crossing) 库。它功能强大、稳定可靠,支持生成和解码多种格式的二维码。另一个备选是 QRGen,它基于 ZXing 但提供了更简化的 API。

方案一:使用 ZXing(推荐,功能最全面)

1. 添加 Maven 依赖

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

<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.5.3</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.5.3</version>
</dependency>

2. 基础二维码生成(保存为图片文件)

这是最基础的用法,几行代码即可将文本内容生成为二维码图片。

import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import java.nio.file.Paths;

public class QRCodeGenerator {
    public static void main(String[] args) throws Exception {
        String content = "https://www.example.com";  // 二维码内容
        String path = "qrcode.png";                   // 输出路径
        int width = 300;
        int height = 300;

        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height);
        MatrixToImageWriter.writeToPath(bitMatrix, "PNG", Paths.get(path));
        
        System.out.println("二维码生成成功:" + path);
    }
}

3. 生成内存中的二维码图片(BufferedImage)

如果你的项目需要将二维码用于 Web 展示、邮件附件或进一步图像处理,可以直接生成 BufferedImage 对象,而无需保存为文件。

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 java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;

public class QRCodeToBufferedImage {

    public static BufferedImage generateQRCodeImage(String content, int width, int height) throws Exception {
        // 配置参数:字符编码和纠错级别
        Map&lt;EncodeHintType, Object&gt; hints = new HashMap&lt;&gt;();
        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);

        // 将 BitMatrix 转换为 BufferedImage
        BufferedImage qrImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x &lt; width; x++) {
            for (int y = 0; y &lt; height; y++) {
                qrImage.setRGB(x, y, bitMatrix.get(x, y) ? Color.BLACK.getRGB() : Color.WHITE.getRGB());
            }
        }
        return qrImage;
    }
}

4. 高级配置

在生成二维码时,可以通过 EncodeHintType 配置多种参数:

Map&lt;EncodeHintType, Object&gt; hints = new HashMap&lt;&gt;();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");          // 字符编码
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 纠错级别(L/M/Q/H)
hints.put(EncodeHintType.MARGIN, 2);                        // 白边宽度(默认4)

方案二:生成带 Logo 的二维码

在二维码中心嵌入 Logo 图标,需要在生成基础二维码后,用 Java AWT 将 Logo 图片绘制到二维码中心位置。

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;

public class QRCodeWithLogo {

    public static BufferedImage addLogoToQRCode(BufferedImage qrImage, String logoPath) throws Exception {
        Graphics2D graphics = qrImage.createGraphics();

        // 读取 Logo 图片
        BufferedImage logoImage = ImageIO.read(new File(logoPath));

        // Logo 大小设为二维码的 1/5(兼顾识别率与美观)
        int logoWidth = qrImage.getWidth() / 5;
        int logoHeight = qrImage.getHeight() / 5;

        // 居中计算
        int x = (qrImage.getWidth() - logoWidth) / 2;
        int y = (qrImage.getHeight() - logoHeight) / 2;

        // 绘制 Logo(带白色背景框,避免干扰二维码识别)
        graphics.setColor(Color.WHITE);
        graphics.fillRect(x - 5, y - 5, logoWidth + 10, logoHeight + 10);
        graphics.drawImage(logoImage, x, y, logoWidth, logoHeight, null);
        graphics.dispose();

        return qrImage;
    }

    public static void main(String[] args) throws Exception {
        BufferedImage qrImage = QRCodeToBufferedImage.generateQRCodeImage("https://www.example.com", 400, 400);
        BufferedImage qrWithLogo = addLogoToQRCode(qrImage, "logo.png");
        
        // 保存到文件
        ImageIO.write(qrWithLogo, "PNG", new File("qrcode_with_logo.png"));
        System.out.println("带 Logo 的二维码生成成功");
    }
}

方案三:使用 QRGen(更简洁的 API)

如果你的需求仅限于生成二维码(不需要解析功能),QRGen 提供了更简洁的 API。

1. 添加 Maven 依赖

<dependency>
    <groupId>net.glxn.qrgen</groupId>
    <artifactId>javase</artifactId>
    <version>2.0</version>
</dependency>

2. 生成二维码

import net.glxn.qrgen.QRCode;
import net.glxn.qrgen.image.ImageType;

import java.io.File;

public class QRGenExample {
    public static void main(String[] args) {
        // 生成二维码并保存为图片文件
        QRCode.from("https://www.example.com")
                .withSize(300, 300)
                .to(ImageType.PNG)
                .writeTo(new File("qrcode_qrgen.png"));

        // 生成二维码并转为字节数组(适合 Web 响应)
        byte[] qrBytes = QRCode.from("Hello QRGen")
                .withSize(200, 200)
                .to(ImageType.PNG)
                .stream()
                .toByteArray();
        
        System.out.println("二维码生成成功");
    }
}

常用工具类封装(Spring Boot 场景)

在实际项目中,通常会将二维码生成逻辑封装为工具类,方便复用。

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.io.ByteArrayOutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class QRCodeUtil {
    public static void generateQRCode(String content, String filePath, int width, int height) 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);
        Path path = Paths.get(filePath);
        MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path);
    }
    public static byte[] generateQRCodeBytes(String content, int width, int height) throws Exception {
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        MatrixToImageWriter.writeToStream(bitMatrix, "PNG", outputStream);
        return outputStream.toByteArray();
    }
}

在 Spring Boot Controller 中直接返回二维码图片:

@GetMapping("/qrcode")
public ResponseEntity&lt;byte[]&gt; generateQRCode(@RequestParam String content) throws Exception {
    byte[] qrBytes = QRCodeUtil.generateQRCodeBytes(content, 300, 300);
    return ResponseEntity.ok()
            .contentType(MediaType.IMAGE_PNG)
            .body(qrBytes);
}

觉得上面的内容有用吗?快来点个赞吧!

点赞() 我要打赏

温馨提示 : 本站内容来自会员投稿以及互联网,所有源码及教程均为作者总结编辑,请大家在使用过程中提前做好备份,以免发生无法预知的错误,源码类教程请勿直接用于生产环境!

 可能感兴趣的文章