java生成二维码

397 阅读4分钟

java生成二维码

既上次发的二维码扫码登录业务详解后 有人说想要一个java版本的生成二维码

所以这篇文章出现了

这里用springboot来实现 相信做java的肯定是用过springboot的

这里直接用的最新的springboot3.3来做的演示

使用谷歌的zxing开源库生成普通的黑白二维码

首先我们引入

需要注意的是zxing是依赖commons-lang的所以我们也要加上去

<!--zxing依赖-->
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.1.0</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.1.0</version>
</dependency><!--commons-lang依赖-->
<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>

之后我们首先来写前端的页面

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>使用java语言生成二维码</title>
</head>
<body>
<h1>使用谷歌的zxing开源库生成普通的黑白二维码</h1>
<hr>
请输入文本内容: <input type="text" id="url"/>
<button onclick="generateQRcode()">生成二维码</button>
<hr>
<img src="" id="qrcodeImg">
</body>
<script>
    function generateQRcode() {
        //获取url
        let url = document.getElementById("url").value;
        let qrcodeImg = document.getElementById("qrcodeImg");
        qrcodeImg.src = "/qrcode/gen?url=" + url
    }
</script>
</html>

可以发现实现的功能:

image-20240713132941310

之后我们来写后端部分

@RestController
@RequestMapping("/qrcode")
public class GenController {
    @GetMapping("/gen")
    public String gen(@RequestParam("url") String url){
        return url;
    }
}

这是一个简单的示例,当请求地址的时候 就会返回对应的url

当然只返回url是不行的,接下来我们就开始要进行生成了

生成的时候我们要知道他的一些常用的参数 API

常用API参数

EncodeHintType(编码提示类型)

EncodeHintType 是用于设置二维码编码时的额外参数的枚举类型,常用枚举值如下:

  • ERROR_CORRECTION:误差校正级别,可选值为 L(7%)、M(15%)、Q(25%)、H(30%),表示二维码允许破损的最大容错率。
  • CHARACTER_SET:编码字符集,例如 utf-8gb2312
  • MARGIN:二维码的空白区域大小。

MultiFormatWriter(多格式写入程序)

MultiFormatWriter 是一个便捷的二维码生成类,可以生成多种格式的二维码,包括 QR CodeAztec CodePDF417Data Matrix 等。

BarcodeFormat(码格式)

BarcodeFormat 是用于指定二维码格式的枚举类:

  • QR Code:常见的二维码格式,广泛应用于商品包装、扫码支付等。
  • Aztec Code:高密度、可靠性高,适合储存核心信息。
  • PDF417:可以储存大量信息,适用于航空机票、运输标签等。
  • Data Matrix:小巧、可靠性高,适合产品标签、医疗图像等。

BitMatrix(位矩阵)

BitMatrix 是表示二维码矩阵的数据结构,由 0 和 1 构成的二维数组,用于存储二维码的编码信息。常用方法包括:

  • getHeight():获取矩阵高度。
  • getWidth():获取矩阵宽度。
  • get(x, y):根据 x,y 坐标获取矩阵中该坐标的值,结果为 true(黑色)或 false(白色)。

在了解了这些之后 我们来写一个工具类

package com.xiaou.qrcodedemo.utils;
​
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
​
import javax.imageio.ImageIO;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
​
public class QRCodeGenerator {
​
    // 生成二维码的方法
    public static void generateQRCode(String url, HttpServletResponse response) {
       try {
          // 准备二维码属性
          Map<EncodeHintType, Object> hints = new HashMap<>();
          hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
          hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
          hints.put(EncodeHintType.MARGIN, 1);
​
          // 创建MultiFormatWriter对象
          MultiFormatWriter writer = new MultiFormatWriter();
          // 生成二维码的位矩阵
          BitMatrix bitMatrix = writer.encode(url, BarcodeFormat.QR_CODE, 300, 300, hints);
​
          // 获取位矩阵的宽度和高度
          int width = bitMatrix.getWidth();
          int height = bitMatrix.getHeight();
​
          // 创建BufferedImage对象
          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) ? 0xFF000000 : 0xFFFFFFFF);
             }
          }
​
          // 设置响应内容类型
          response.setContentType("image/png");
          ServletOutputStream out = response.getOutputStream();
          ImageIO.write(image, "png", out);
          out.flush();
          out.close();
       } catch (WriterException | IOException e) {
          e.printStackTrace();
       }
    }
}

之后我们进行一个调用:

@GetMapping("/gen")
public void gen(@RequestParam("url") String url, HttpServletResponse response){
    QRCodeGenerator.generateQRCode(url, response);
}

可以发现已经ok了

image-20240713134932079

我们也可以进行扫码 发现就打开了哔哩哔哩

这个只是一个普通的二维码

这个时候我们就会发现一些问题。

就是一个这么简单的二维码 我们需要去设置的东西有很多很多 那么有没有什么方法可以快速的开发呢?

当然是有的

下面我就来介绍一个github的项目

使用github开源项目qrcode-plugin生成

首先我们引入依赖

<dependency>
    <groupId>com.github.liuyueyi.media</groupId>
    <artifactId>qrcode-plugin</artifactId>
    <version>2.5.2</version>
</dependency>

这个能生成很多样式的。

我这里写了一个工具类:

package com.xiaou.qrcodedemo.utils;
​
import com.github.hui.quick.plugin.qrcode.wrapper.QrCodeGenWrapper;
import com.github.hui.quick.plugin.qrcode.wrapper.QrCodeOptions;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
​
import java.awt.Color;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import jakarta.servlet.http.HttpServletResponse;
import java.io.InputStream;
​
public class QRCodeGenerator {
​
    // 生成黑白二维码
    public static void generateBlackAndWhiteQRCode(String url, HttpServletResponse response) throws Exception {
        BufferedImage image = QrCodeGenWrapper.of(url).asBufferedImage();
        ImageIO.write(image, "png", response.getOutputStream());
    }
​
    // 生成带有logo的二维码
    public static void generateQRCodeWithLogo(String url, HttpServletResponse response, InputStream logoStream) throws Exception {
        BufferedImage image = QrCodeGenWrapper.of(url)
                .setLogo(logoStream)
                .setLogoRate(7)
                .setLogoStyle(QrCodeOptions.LogoStyle.ROUND)
                .asBufferedImage();
        ImageIO.write(image, "png", response.getOutputStream());
    }
​
    // 生成彩色二维码
    public static void generateColorQRCode(String url, HttpServletResponse response) throws Exception {
        BufferedImage image = QrCodeGenWrapper.of(url)
                .setDrawPreColor(Color.BLUE)
                .asBufferedImage();
        ImageIO.write(image, "png", response.getOutputStream());
    }
​
    // 生成背景图二维码
    public static void generateBackgroundImageQRCode(String url, HttpServletResponse response, InputStream bgImgStream) throws Exception {
        BufferedImage image = QrCodeGenWrapper.of(url)
                .setBgImg(bgImgStream)
                .setBgOpacity(0.7F)
                .asBufferedImage();
        ImageIO.write(image, "png", response.getOutputStream());
    }
​
    // 特殊形状二维码
    public static void generateSpecialShapeQRCode(String url, HttpServletResponse response) throws Exception {
        BufferedImage image = QrCodeGenWrapper.of(url)
                .setDrawEnableScale(true)
                .setDrawStyle(QrCodeOptions.DrawStyle.DIAMOND)
                .asBufferedImage();
        ImageIO.write(image, "png", response.getOutputStream());
    }
​
    // 图片填充二维码
    public static void generateImageFilledQRCode(String url, HttpServletResponse response, InputStream imgStream) throws Exception {
        BufferedImage image = QrCodeGenWrapper.of(url)
                .setErrorCorrection(ErrorCorrectionLevel.H)
                .setDrawStyle(QrCodeOptions.DrawStyle.IMAGE)
                .addImg(1, 1, imgStream)
                .asBufferedImage();
        ImageIO.write(image, "png", response.getOutputStream());
    }
​
    // 生成gif动图二维码
    public static void generateGifQRCode(String url, HttpServletResponse response, InputStream bgImgStream) throws Exception {
        BufferedImage image = QrCodeGenWrapper.of(url)
                .setW(500)
                .setH(500)
                .setBgImg(bgImgStream)
                .setBgOpacity(0.6f)
                .setPicType("gif")
                .asBufferedImage();
        ImageIO.write(image, "gif", response.getOutputStream());
    }
}
​

这里有着很多的方式

案例演示

image-20240713140635075

这个就是结合了上面所说的所有的东西

李子凡/qrcode-demo (gitee.com)

源码在这里有兴趣的可以去查看