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>
可以发现实现的功能:
之后我们来写后端部分
@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-8、gb2312。MARGIN:二维码的空白区域大小。
MultiFormatWriter(多格式写入程序)
MultiFormatWriter 是一个便捷的二维码生成类,可以生成多种格式的二维码,包括 QR Code、Aztec Code、PDF417、Data 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了
我们也可以进行扫码 发现就打开了哔哩哔哩
这个只是一个普通的二维码
这个时候我们就会发现一些问题。
就是一个这么简单的二维码 我们需要去设置的东西有很多很多 那么有没有什么方法可以快速的开发呢?
当然是有的
下面我就来介绍一个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());
}
}
这里有着很多的方式
案例演示
这个就是结合了上面所说的所有的东西
源码在这里有兴趣的可以去查看