Java怎么生成二维码?

191 阅读4分钟

二维码在许多项目中都有广泛的应用,它们为信息的快速分享和获取提供了一种方便的方式。例如我们可以把广告海报、产品描述、链接等信息放到二维码中。

那么怎么在一个spring项目中集成二维码功能呢?

今天来介绍两种二维码生成工具。

ZXing

ZXing(Zebra Crossing)是一个Google开发的开源的、多功能的1D/2D条码图像处理库,由Java语言编写,主要用于Java平台但也有其他语言的移植版本。

下面我用一个SpringBoot项目来介绍下ZXing怎么使用。

首先新建一个SpringBoot项目,勾选web模块。

Snipaste_2023-10-18_18-28-59.png

Snipaste_2023-10-18_18-29-33.png

引入ZXing的依赖(以Maven为例)

Snipaste_2023-10-18_19-17-30.png

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

封装工具类

新建一个名为ZXingQRCodeUtil的工具类,主要分为三个步骤:

  • 创建Map存放配置
  • 生成二维码
  • 返回PNG格式的字节流

完整代码如下。

Snipaste_2023-10-18_19-17-57.png

package cn.laoj.qrcode.util;


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.client.j2se.MatrixToImageWriter;


import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;


/**
 * 利用zxing生成二维码
 * @author 公众号【程序员老J】
 * @date 2023-10-18
 */
public class ZXingQRCodeUtil {




    public static byte[] generateQRCodeImage(String data) throws Exception {
        BufferedImage image = generateQRCodeAsBufferedImage(data);
        //将BufferedImage转换为字节流输出
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "PNG", outputStream);
        return outputStream.toByteArray();
    }


    private static BufferedImage generateQRCodeAsBufferedImage(String data) throws Exception {
        //创建一个HashMap,用于存放二维码的编码配置
        Map<EncodeHintType, Object> hintMap = new HashMap<>();
        //设置二维码的错误纠正级别为"L"(低级)
        hintMap.put(EncodeHintType.ERROR_CORRECTION, com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.L);
        hintMap.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        //将配置和输入的信息生成二维码的BufferedImage
        BitMatrix matrix = new MultiFormatWriter().encode(
                data,
                BarcodeFormat.QR_CODE, 200, 200, hintMap);
        return MatrixToImageWriter.toBufferedImage(matrix);
    }


}

有的小伙伴可能会问,二维码的纠错级别是什么意思呢?

二维码的错误纠正是指当二维码部分损坏或模糊时,它还可以恢复和读取的能力。通常是纠错级别越高,存储的数据越少,这是因为二维码中存储了很多重复数据。 二维码的错误纠正有四个级别:

  • L(Low):约可纠正最大7%的错误。
  • M(Medium):约可纠正最大15%的错误。
  • Q(Quartile):约可纠正最大25%的错误。
  • H(High):约可纠正最大30%的错误。

我们这里设置二维码的错误纠正级别为'L'时,指的是二维码中最多7%部分被损坏或模糊时,读取器仍然可以正确解码!

controller层

工具类封装好之后就可以在controller层调用了。完整代码如下。

Snipaste_2023-10-18_19-18-27.png

package cn.laoj.qrcode.controller;


import cn.laoj.qrcode.util.QRCodeHutoolUtil;
import cn.laoj.qrcode.util.ZXingQRCodeUtil;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;


/**
 * 生成二维码的controller
 * @author 公众号【程序员老J】
 * @date 2023-10-18
 */
@RestController
public class QRCodeController {


    //利用zxing生成二维码
    @PostMapping(value = "/generateQRCode", produces = MediaType.IMAGE_PNG_VALUE)
    public ResponseEntity<byte[]> generateQRCode(@RequestBody String data) throws Exception {
        byte[] imageBytes = ZXingQRCodeUtil.generateQRCodeImage(data);
        return ResponseEntity.ok().contentType(MediaType.IMAGE_PNG).body(imageBytes);
    }


}

这里我们定义produces属性为PNG类型,顺便来回顾一下produces属性

produces属性指定的值是MIME类型,用于定义数据的类型和格式。下面是一些常见的produces可能的值:

图片.png

postman测试

接下来启动项目然后用postman进行测试。将body改为raw格式,输入想生成的字符串就可以了!

Snipaste_2023-10-18_19-22-02.png

HuTool

提到工具类,必须得介绍万能的HuTool了。Hutool是一个小而全的Java工具类库。HuTool生成二维码本质上也是对ZXing的封装,只不过写法更加简洁。

引入HuTool依赖(以Maven为例)

Snipaste_2023-10-18_19-22-44.png

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.10</version>
</dependency>

封装工具类

对比ZXing的方式,HuTool步骤非常简单,只需要定义二维码的大小即可!下面是完整代码。

Snipaste_2023-10-18_19-22-50.png

package cn.laoj.qrcode.util;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
/**
 * 利用hutool生成二维码
 * @author 公众号【程序员老J】
 * @date 2023-10-18
 */
public class QRCodeHutoolUtil {


    public static byte[] generateQRCodeImage(String data) throws Exception {
        QrConfig config = new QrConfig(200, 200);
        BufferedImage image = QrCodeUtil.generate(data, config);
        //将BufferedImage装换为字节流
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "PNG", outputStream);
        return outputStream.toByteArray();
    }
}

controller层

Snipaste_2023-10-18_19-23-20.png

package cn.laoj.qrcode.controller;

import cn.laoj.qrcode.util.QRCodeHutoolUtil;
import cn.laoj.qrcode.util.ZXingQRCodeUtil;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * 生成二维码的controller
 * @author 公众号【程序员老J】
 * @date 2023-10-18
 */
@RestController
public class QRCodeController {



    //利用hutool生成二维码
    @PostMapping(value = "/generateQRCodeHutool", produces = MediaType.IMAGE_PNG_VALUE)
    public ResponseEntity<byte[]> generateQRCodeHuTool(@RequestBody String data) throws Exception {
        byte[] imageBytes = QRCodeHutoolUtil.generateQRCodeImage(data);
        return ResponseEntity.ok().contentType(MediaType.IMAGE_PNG).body(imageBytes);
    }
}

postman测试

同样我们使用postman对接口进行测试。

Snipaste_2023-10-18_19-24-57.png

总结

ZXing和HuTool都可以生成二维码,HuTool是对ZXing的进一步封装,写法更加简洁,推荐使用HuTool!

更多文章干货,推荐公众号【程序员老J】