「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战」
前言
以前的一个老项目里使用过ZXing进行会员和门店二维码的生成操作,当时出现过Java版本升级后不兼容的问题,很是麻烦,于是替换成了hutool里的二维码生成,下面我们来看看具体的实现。
一.带Logo的二维码生成的原理,绘制一个自定义长宽的底图,当然也可以使用一张图片作为底图,然后获取带Logo的本地图片,将Logo图片‘放到’底图上,再将整个图片以流都形式输出
二.具体的实现 1.生成二维码到文件,这种形式很常用
public static File generate(String content, int width, int height, File targetFile) {
//进行图片绘制
final BufferedImage image = generate(content, width, height);
ImgUtil.write(image, targetFile);
return targetFile;
}
1)对图片生成代码部分进行解读
public static BufferedImage generate(String content, BarcodeFormat format, QrConfig config) {
//先进行将文本内容编码为条形码或二维码
final BitMatrix bitMatrix = encode(content, format, config);
//将BitMatrix转BufferedImage 这里转为BufferedImage是为了后面能够拿到Logo的长和宽
final BufferedImage image = toImage(bitMatrix, config.foreColor, config.backColor);
final Image logoImg = config.img;
if (null != logoImg && BarcodeFormat.QR_CODE == format) {
// 二维码贴图长和宽获取
final int qrWidth = image.getWidth();
final int qrHeight = image.getHeight();
int width;
int height;
// 按照最短的边做比例缩放
if (qrWidth < qrHeight) {
width = qrWidth / config.ratio;
height = logoImg.getHeight(null) * width / logoImg.getWidth(null);
} else {
height = qrHeight / config.ratio;
width = logoImg.getWidth(null) * height / logoImg.getHeight(null);
}
Img.from(image).pressImage(//
// 圆角处理,不处理的话 Logo在底图中央就看起来很怪异
Img.from(logoImg).round(0.3).getImg(),
new Rectangle(width, height),
);
}
return image;
}
- 生成带Logo图片的Base64 编码格式的二维码,以 String 形式返回,这种不是很常用
//生成图片的主要代码
final BufferedImage img = generate(content, qrConfig);
//将图片对象转换为Base64的Data URI形式
public static String toBase64DataUri(Image image, String imageType) {
return URLUtil.getDataUri(
"image/" + imageType, "base64",
toBase64(image, imageType));
}
3.还有返回BufferedImage和BitMatrix的方法,可以由我们去自行去处理,不是很常用,或者目前的业务还没有使用到,感兴趣的小伙伴可以试试。
小结
hutool里不管是对于FTP还是二维码的生成,我们都可以看到,并没有将方法固定,而且同时提供了一些额外的方法,供我们能够自定义去处理,这点对于遇到业务复杂的小伙伴十分友好。