java 实现二维码生成工具类
时间:2022-04-27
本文章向大家介绍java 实现二维码生成工具类,主要内容包括二维码工具篇、2. 实现说明、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
二维码工具篇
利用google的开源库
zxing
来实现二维码的生成,并实际修复一些常见的问题
项目地址: http://git.oschina.net/liuyueyi/quicksilver
1. 设计思路
二维码生成,采用现在用得比较多的开源框架
Zxing
既然都不是自己来生成二维码了,为什么要做这个东西呢? 我要生成二维码直接用官方的api不就行了,你这个不是化蛇添足么!!!
- 官方的接入比较麻烦,特别是你想定制生成个性化的二维码时,需要了解到zxing内部的一些设置参数,这个工具则降低了这些成本,与zxing打交道的配置都有它来做,对外暴露一些友好的,易懂的参数配置 - 实现对实际二维码生成工具的解耦,假设zxing被爆出了什么安全漏洞,这里进行切换别的框架相对成本更低 - 个性化的定制 (如加logo)
目标
- 最开始是希望设计个通用的,与具体的二维码生成工具解耦(即作为一个适配器层),实际上没这么玩... - 制定对外暴露的配置项,用户根据需要设置二维码生成的参数,生成二维码 - 即对用户而言,就两部,设置参数, 生成二维码, 总得交互就两个接口
设计
- 设置参数采用builder模式, 生成配置项 - 一个适配层,将配置项适配为zxing的二维码生成参数 - 实际的处理层,生成二维码 - 输出层,可以根据需求选择输出方式(输出为stream, 文件, bufferedImage)
2. 实现说明
- 配置参数 约定二维码生成的参数如下
/**
* The message to put into QrCode
*/
private String msg;
/**
* qrcode center logo
*/
private String logo;
/**
* qrcode image width
*/
private Integer w;
/**
* qrcode image height
*/
private Integer h;
/**
* qrcode bgcolor, default white
*/
private Integer offColor;
/**
* qrcode msg color, default black
*/
private Integer onColor;
/**
* qrcode message's code, default UTF-8
*/
private String code;
/**
* 0 - 4
*/
private Integer padding;
/**
* error level, default H
*/
private ErrorCorrectionLevel errorCorrection;
/**
* output qrcode image type, default png
*/
private String picType;
```
- 二维码生成
生成二维码核心代码
`QRCode code = Encoder.encode(qrCodeConfig.getMsg(), errorCorrectionLevel, qrCodeConfig.getHints());`
生成的code中, 就包含了二维码矩阵, 剩下的就是将矩阵渲染输出的问题, 输出没什么好说的,这里指出一点原生的zxing生成二维码的白边可能特别大,本工具类内部做了兼容,[点我查看大白边修复指南](https://my.oschina.net/u/566591/blog/872770)
```java
/**
* 对 zxing 的 QRCodeWriter 进行扩展, 解决白边过多的问题
* <p/>
* 源码参考 {@link com.google.zxing.qrcode.QRCodeWriter#encode(String, BarcodeFormat, int, int, Map)}
*/
private static BitMatrix encode(QrCodeConfig qrCodeConfig) throws WriterException {
ErrorCorrectionLevel errorCorrectionLevel = ErrorCorrectionLevel.L;
int quietZone = 1;
if (qrCodeConfig.getHints() != null) {
if (qrCodeConfig.getHints().containsKey(EncodeHintType.ERROR_CORRECTION)) {
errorCorrectionLevel = ErrorCorrectionLevel.valueOf(qrCodeConfig.getHints().get(EncodeHintType.ERROR_CORRECTION).toString());
}
if (qrCodeConfig.getHints().containsKey(EncodeHintType.MARGIN)) {
quietZone = Integer.parseInt(qrCodeConfig.getHints().get(EncodeHintType.MARGIN).toString());
}
if (quietZone > QUIET_ZONE_SIZE) {
quietZone = QUIET_ZONE_SIZE;
} else if (quietZone < 0) {
quietZone = 0;
}
}
QRCode code = Encoder.encode(qrCodeConfig.getMsg(), errorCorrectionLevel, qrCodeConfig.getHints());
return renderResult(code, qrCodeConfig.getW(), qrCodeConfig.getH(), quietZone);
}
```
## 3. 使用说明
写完了就要开始实际用,写了个测试类,贴出如下
```java
/**
* 测试二维码
*/
@Test
public void testGenQrCode() {
String msg = "create qrcode!!!";
// 简单的生成
QrCodeConfig qrCodeConfig = QrCodeGenWrapper.createQrCodeConfig()
.setMsg(msg)
.build();
try {
boolean ans = QrCodeGenWrapper.asFile(qrCodeConfig, "qrcode/gen.png");
System.out.println(ans);
} catch (Exception e) {
System.out.println("create qrcode error! e: " + e);
Assert.assertTrue(false);
}
//生成红色的二维码 300x300, 无边框
try {
boolean ans = QrCodeGenWrapper.createQrCodeConfig()
.setMsg(msg)
.setW(300)
.setOnColor(0xffff0000)
.setOffColor(0xffffffff)
.setPadding(0)
.asFile("qrcode/gen_300x300.png");
System.out.println(ans);
} catch (Exception e) {
System.out.println("create qrcode error! e: " + e);
Assert.assertTrue(false);
}
// 生成带logo的二维码
try {
String logo = "https://git.oschina.net/uploads/34/2334_liuyueyi.png";
boolean ans = QrCodeGenWrapper.createQrCodeConfig()
.setMsg(msg)
.setW(300)
.setOnColor(0xffff0000)
.setOffColor(0xffffffff)
.setPadding(0)
.setLogo(logo)
.asFile("qrcode/gen_300x300_logo.png");
System.out.println(ans);
} catch (Exception e) {
System.out.println("create qrcode error! e: " + e);
Assert.assertTrue(false);
}
// 根据本地文件生成待logo的二维码
try {
String logo = "qrcode/logo.png";
boolean ans = QrCodeGenWrapper.createQrCodeConfig()
.setMsg(msg)
.setW(300)
.setOnColor(0xffff0000)
.setOffColor(0xffffffff)
.setPadding(0)
.setLogo(logo)
.asFile("qrcode/gen_300x300_logo_v2.png");
System.out.println(ans);
} catch (Exception e) {
System.out.println("create qrcode error! e: " + e);
Assert.assertTrue(false);
}
}
从上面可以看出,实际用的时候有两种方式,没什么特别的,看自己需求选择使用 - 先生成配置项, 然后根据配置项生成二维码 - 设置参数,然后直接调用build的生成二维码方法
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 深入探究immutable.js的实现机制(二)
- ES6 Promise 的最佳实践
- 「 Map最佳实践」什么时候适合使用 Map 而不是 Object
- ES2017 异步函数的最佳实践(`async` /`await`)
- React Hooks中这样写HTTP请求可以避免内存泄漏
- 用了这 7 个 VS Code 插件,想写一辈子代码
- 听说你还不知道Promise的allSettled()和all()的区别?
- React 条件渲染最佳实践(7 种方法)
- 一文带你层层解锁「文件下载」的奥秘
- Android实现简单C/S聊天室应用
- Android仿IOS回弹效果 支持任何控件
- 送你一道字节前端原题(Add sumOf)|文末送红宝书
- xadmin使用formfield_for_dbfield函数过滤下拉表单实例
- Python3之外部文件调用Django程序操作model等文件实现方式
- python 在右键菜单中加入复制目标文件的有效存放路径(单斜杠或者双反斜杠)