!1165 QrCodeUtil 增加ECI配置,解决扫码桩扫描二维码 出现类似:"\000026"的问题

* QrCodeUtil 增加ECI配置,解决扫码桩扫描二维码 出现类似:"\000026"的问题
This commit is contained in:
dazer007 2024-01-24 08:39:33 +00:00 committed by Looly
parent dd1ec90fd4
commit 1fff2001be
2 changed files with 52 additions and 2 deletions

View File

@ -66,6 +66,29 @@ public class QrConfig {
*/
protected ErrorCorrectionLevel errorCorrection = ErrorCorrectionLevel.M;
/**
* 是否开启ECI编码<br>
* 如果enableEci=false,则二维码中不包含ECI信息{@link #charset}字符编码设置无效, 二维码为英文字符保持false最佳<br>
* 如果enableEci=true,则二维码中包含ECI信息按照{@link #charset}编码进行设置, 二维码为包含中文保持true最佳否则会中文乱码<br>
*
* 参考1<a href="https://github.com/nutzam/nutz-qrcode/issues/6">关于\000026的问题</a>
* 参考2<a href="https://en.wikipedia.org/wiki/Extended_Channel_Interpretation">ECIExtended_Channel_Interpretation模式</a> <br><br>
* 参考3<a href="https://www.51cto.com/article/414082.html">二维码的生成细节和原理</a> <br><br>
* <p>二维码编码有ECI模式和非ECI模式的情况之分在ECI模式下第一个字节是用作编码标识而非ECI模式下直接就是数据流
* ECI模式其实是更好的方案这样子解码的时候可以根据标识采用不同的编码方式而非ECI模式只能按照一种统一的方式处理了
* 但是由于部分设备不支持ECI模式所以就出现了无法识别的情况
* 使用扫码桩/扫码枪可能会出现\000026的字符使用手机扫描其他二维码解析软件扫描则不会出现
* </p>
*
* <p>
* ECI编码表可以看出UTF-8就是对应"\000026"对应数字22<br><br>
* </p>
*
* <p> 总结建议如果二维码内容全是字符没有中文就不用使用UTF-8等格式进行编码只有使用中文等特殊符号才需要编码 </p>
*
* @see EncodeHintType#PDF417_AUTO_ECI
*/
protected Boolean enableEci = false;
/**
* 编码
*/
protected Charset charset = CharsetUtil.UTF_8;
@ -266,6 +289,26 @@ public class QrConfig {
return errorCorrection;
}
/**
* 获取是否开启了ECI编码
*
* @return 是否开启ECI编码true: 开启false: 未开启默认未开启
*/
public Boolean getEnableEci() {
return enableEci;
}
/**
* 设置二维码是否开启ECI编码部分老设备不兼容该模式建议不开启
*
* @param enableEci 二维码是否开启ECI编码
*/
public void setEnableEci(Boolean enableEci) {
if (enableEci == null) {
this.enableEci = enableEci;
}
}
/**
* 设置纠错级别
*
@ -407,8 +450,12 @@ public class QrConfig {
public HashMap<EncodeHintType, Object> toHints() {
// 配置
final HashMap<EncodeHintType, Object> hints = new HashMap<>();
if (null != this.charset) {
hints.put(EncodeHintType.CHARACTER_SET, charset.toString().toLowerCase());
// 只有不禁用即开启ECI编码功能才使用自定义的字符编码
// 二维码内容就是英文字符建议不设置编码没有任何问题对于中文来说会乱码
if (this.enableEci) {
if (null != this.charset) {
hints.put(EncodeHintType.CHARACTER_SET, charset.toString().toLowerCase());
}
}
if (null != this.errorCorrection) {
final Object value;

View File

@ -49,6 +49,9 @@ public class QrCodeUtilTest {
final QrConfig config = QrConfig.of();
config.setMargin(0);
config.setForeColor(Color.CYAN);
// 关闭ECI模式部分老设备不支持ECI编码 如果二维码中包含中文则需要必须开启此配置
// 现象使用三方识别二维码工具手机微信支付宝扫描正常使用扫码桩扫码枪识别会多出来类似\000026\000029字符
config.setEnableEci(false);
// 背景色透明
config.setBackColor(null);
config.setErrorCorrection(ErrorCorrectionLevel.H);