总所周知,二维码的内容越多,二维码越复杂,越是复杂的二维码扫码效率越慢,有时候导致直接扫码的时候直接扫不出来。
解决方法:
在生成二维码的时候,对二维码文本进行压缩,压缩内容生成二维码,在扫码的时候,把扫码获取的压缩内容传给后台,然后进行二维码解压即可获取解压内容。
具体实现方法如下:
1. 引入pom文件
<!--二维码解析-->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.3</version>
</dependency>
2. 写测试类
public static void main(String[] args) throws IOException, NotFoundException {
String content="假设这个文本的内容超级长";
//压缩
String zipContent=zipBase64(content);
System.out.println("压缩内容"+zipContent);
//生成二维码
QRCodeUtil.getQRCode(zipContent,"jpg","G:/img/testQr2.jpg","UTF-8");
//获取二维码路径
String format="G:/img/testQr2.jpg";
//获取压缩内容
String analysis = QRCodeUtil.analysis(format, "UTF-8");
//解压已压缩内容
String unzipBase64 = unzipBase64(analysis);
System.out.println(unzipBase64);
}
3. 结果:
生成的图片如下:
控制台输出:
4.工具类
压缩解压文本:
/**
* 压缩文本
* @param text
* @return
*/
public static String zipBase64(String text) {
//创建一个新的字节数组输出流。缓冲区容量最初为 32 字节
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
//使用默认压缩器和缓冲区大小创建新的输出流
try (DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(out)) {
deflaterOutputStream.write(text.getBytes(Charset.forName("UTF-8")));
}
return Base64.getEncoder().encodeToString(out.toByteArray());
} catch (IOException e) {
}
return "";
}
/**
* 解压文本
* @param text
* @return
*/
public static String unzipBase64(String text) {
try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
//使用默认解压缩器和缓冲区创建新的输出流
try (OutputStream outputStream = new InflaterOutputStream(os)) {
outputStream.write(Base64.getDecoder().decode(text.getBytes()));
}
return new String(os.toByteArray(), Charset.forName("UTF-8"));
} catch (IOException e) {
}
return "";
}
生成二维码,解析二维码工具:
package com.excel.util;
import cn.hutool.extra.qrcode.BufferedImageLuminanceSource;
import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
/**
* 二维码的解析,生成
* @author lenovo
*/
public class QRCodeUtil {
/**
* 生成二维码
* @param contents 内容
* @param format 二维码图片后缀
* @param filepath //生成二维码路径(当包含二维码名称和后缀,忽略format)
* @throws IOException
* @throws NotFoundException
*/
public static void getQRCode(String contents,String format,String filepath) throws IOException, NotFoundException {
getQRCode(contents, format, filepath,"utf-8");
}
/**
* 生成二维码
* @param contents 内容
* @param format 二维码图片后缀
* @param filepath //生成二维码路径(当包含二维码名称和后缀,忽略format)
* @param character 二维码内容编码方式
* @throws IOException
* @throws NotFoundException
*/
public static void getQRCode(String contents,String format,String filepath,String character) throws IOException, NotFoundException {
getQRCode(300,300,contents,format,filepath,character);
}
/**
* 生成二维码
* @param width 宽
* @param height 高
* @param contents 内容
* @param format 二维码图片后缀
* @param filepath //生成二维码路径(当包含二维码名称和后缀,忽略format)
* @param character 二维码内容编码方式
* @throws IOException
* @throws NotFoundException
*/
public static void getQRCode(int width,int height,String contents,String format,String filepath,String character) throws IOException, NotFoundException {
HashMap map = new HashMap();
map.put(EncodeHintType.CHARACTER_SET,character);
map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
map.put(EncodeHintType.MARGIN, 0);
try {
BitMatrix bm = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height,map);
Path file = new File(filepath).toPath();
MatrixToImageWriter.writeToPath(bm, format, file);
} catch (WriterException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 解析上传二维码内容(直解析utf-8和GBK编码的二维码)
* @param QRImg 二维码图片内容
* @throws IOException
* @throws NotFoundException
*/
public static String analysis(File QRImg) throws IOException, NotFoundException {
BufferedImage image = ImageIO.read(QRImg);
BinaryBitmap bb = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(image)));
HashMap map = new HashMap();
map.put(DecodeHintType.CHARACTER_SET, "utf-8");
Result result = new MultiFormatReader().decode(bb, map);
String QRContents=result.getText();
if (result.getText().contains("�")){
//乱码了,更换编码方式
System.out.println("乱码了,更换编码格式(GBK)");
map.put(DecodeHintType.CHARACTER_SET, "GBK");
result = new MultiFormatReader().decode(bb, map);
QRContents=result.getText();
}
System.out.println("二维码文本内容:"+QRContents);
return QRContents;
}
/**
* 解析本地二维码内容(直解析utf-8和GBK编码的二维码)
* @param filePath 二维码图片地址
* @throws IOException
* @throws NotFoundException
*/
public static String analysis(String filePath) throws IOException, NotFoundException {
BufferedImage image = ImageIO.read(new File(filePath));
BinaryBitmap bb = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(image)));
HashMap map = new HashMap();
map.put(DecodeHintType.CHARACTER_SET, "utf-8");
Result result = new MultiFormatReader().decode(bb, map);
String QRContents=result.getText();
if (result.getText().contains("�")){
//乱码了,更换编码方式
System.out.println("乱码了,更换编码格式(GBK)");
map.put(DecodeHintType.CHARACTER_SET, "GBK");
result = new MultiFormatReader().decode(bb, map);
QRContents=result.getText();
}
System.out.println("二维码文本内容:"+QRContents);
return QRContents;
}
/**
* 解析本地二维码内容,自定义编码格式
* @param filePath 二维码图片地址
* @param character 二维码内容编码格式
* @throws IOException
* @throws NotFoundException
*/
public static String analysis(String filePath,String character) throws IOException, NotFoundException {
BufferedImage image = ImageIO.read(new File(filePath));
BinaryBitmap bb = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(image)));
HashMap map = new HashMap();
map.put(DecodeHintType.CHARACTER_SET,character);
map.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
//复杂模式
map.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
Result result = new MultiFormatReader().decode(bb, map);
String QRContents=result.getText();
return QRContents;
}
/**
* 解析二维码,此方法解析一个路径的二维码图片(带logo)
* path:二维码图片路径
*/
public static String deEncodeByPath(String path) {
String content = null;
BufferedImage image;
try {
image = ImageIO.read(new File(path));
LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
hints.put(DecodeHintType.CHARACTER_SET, "GBK");
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解码
System.out.println("图片中内容: ");
System.out.println("content: " + result.getText());
content = result.getText();
} catch (IOException e) {
e.printStackTrace();
} catch (NotFoundException e) {
//这里判断如果识别不了带LOGO的图片,重新添加上一个属性
try {
image = ImageIO.read(new File(path));
LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
//设置编码格式
hints.put(DecodeHintType.CHARACTER_SET, "GBK");
//设置优化精度
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
//设置复杂模式开启(我使用这种方式就可以识别微信的二维码了)
hints.put(DecodeHintType.PURE_BARCODE,Boolean.TYPE);
Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解码
System.out.println("图片中内容: ");
System.out.println("content: " + result.getText());
content = result.getText();
} catch (IOException e1) {
e1.printStackTrace();
} catch (NotFoundException e2) {
e2.printStackTrace();
}
}
return content;
}
}