Zxing生成Qrcode 工具类
1、引入依赖
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>${zxing.version}</version>
</dependency>
<zxing.version>3.4.0</zxing.version>
2、QrCodeUtils.java
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.*;
import com.google.zxing.qrcode.QRCodeReader;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.insectcontrol.common.FileType;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Hashtable;
import java.util.Map;
import java.util.Objects;
/**
* 使用ZXing操作二维码(二维码生成和读的工具类), 二维码图片默认PNG格式
* @author
* @date 2019/06/07
*/
public class QrCodeUtils {
/**
* 文本编码格式:UTF-8
*/
public static final String CHARSET_DEF = "UTF-8";
/**
* 图案颜色:黑色
*/
public static final int BLACK = 0xFF000000;
/**
* 背景色:白色
*/
public static final int WHITE = 0xFFFFFFFF;
/**
* 图片最大值:1024
*/
public static final int MAX_SIZE = 1024;
/**
* 图片最小值:400
*/
public static final int MIN_SIZE = 400;
/**
* 编码提示配置
*/
public static final Map<EncodeHintType, Object> HINTS = new Hashtable<EncodeHintType, Object>() {
private static final long serialVersionUID = 1L;
{
// 指定纠错等级,纠错级别(L 7%、M 15%、Q 25%、H 30%)
put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
// 内容所使用字符集编码
put(EncodeHintType.CHARACTER_SET, CHARSET_DEF);
// put(EncodeHintType.MAX_SIZE, MAX_SIZE);//设置图片的最大值
// put(EncodeHintType.MIN_SIZE, MIN_SIZE);//设置图片的最小值
put(EncodeHintType.MARGIN, 0);//设置二维码边的空度,非负数
}};
/**
* 解码配置
*/
public static final Map<DecodeHintType, Object> DECODER_HINTS = new Hashtable<DecodeHintType, Object>() {
private static final long serialVersionUID = 11L;
{
put(DecodeHintType.CHARACTER_SET, CHARSET_DEF); // 防止中文乱码
}
};
/**
* 生成包含字符串信息的二维码图片
* @param outputStream 输出流
* @param content 内容
* @param qrCodeSize 二维码尺寸
* @param imageFormat 图片格式(默认PNG格式)
* @return
* @throws
*/
public static boolean createQrCode(OutputStream outputStream, String content, int qrCodeSize, String imageFormat)
throws WriterException, IOException {
content = new String(content.getBytes(CHARSET_DEF), "ISO-8859-1");
Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<>();
hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
QRCodeWriter qrCodeWriter = new QRCodeWriter();
//创建比特矩阵(位矩阵)的QR码编码的字符串
BitMatrix byteMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, hintMap);
// 使BufferedImage勾画QRCode (matrixWidth 是行二维码像素点)
int matrixWidth = byteMatrix.getWidth();
BufferedImage image = new BufferedImage(matrixWidth-200, matrixWidth-200, BufferedImage.TYPE_INT_RGB);
image.createGraphics();
Graphics2D graphics = (Graphics2D)image.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, matrixWidth, matrixWidth);
// 使用比特矩阵画并保存图像
graphics.setColor(Color.BLACK);
for(int i = 0; i < matrixWidth; i++) {
for(int j = 0; j < matrixWidth; j++) {
if(byteMatrix.get(i , j)) {
graphics.fillRect(i-100, j-100, 1, 1);
}
}
}
return ImageIO.write(image, StringUtil.trim(imageFormat, FileType.PNG.getSuffix()), outputStream);
}
/**
* 生成包含字符串信息的二维码图片
* @param fileFullPath 文件完整路径
* @param content 内容
* @param qrCodeSize 二维码尺寸
* @param imageFormat 图片格式
* @return
* @throws WriterException
* @throws IOException
*/
public static boolean createQrCode(String fileFullPath, String content, int qrCodeSize, String imageFormat)
throws WriterException, IOException {
return createQrCode(new File(fileFullPath), content, qrCodeSize, imageFormat);
}
/**
* 生成包含字符串信息的二维码图片
* @param file 文件
* @param content 内容
* @param qrCodeSize 二维码尺寸
* @param imageFormat 图片格式
* @return
* @throws WriterException
* @throws IOException
*/
public static boolean createQrCode(File file, String content, int qrCodeSize, String imageFormat)
throws WriterException, IOException {
return createQrCode(new FileOutputStream(file), content, qrCodeSize, imageFormat);
}
/**
* 生成带Logo的条形码
* @param qrCodeSrc 条形码文件
* @param logoSrc Logo文件
* @param content 内容
* @param qrCodeWidth 条形码宽度
* @param qrCodeHeight 条形码高度
* @param imageFormat 条形码文件格式(默认PNG格式)
* @return
*/
public static boolean createQrCodeAndLogo(File qrCodeSrc, File logoSrc, String content, int qrCodeWidth,
int qrCodeHeight, String imageFormat)
throws WriterException, IOException {
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
BufferedImage image = new BufferedImage(qrCodeWidth, qrCodeHeight, BufferedImage.TYPE_INT_RGB);
// 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
BitMatrix matrix = multiFormatWriter.encode(content,//要编码的内容
//编码类型,目前zxing支持:Aztec 2D,CODABAR 1D format,Code 39 1D,Code 93 1D ,Code 128 1D,
//Data Matrix 2D , EAN-8 1D,EAN-13 1D,ITF (Interleaved Two of Five) 1D,
//MaxiCode 2D barcode,PDF417,QR Code 2D,RSS 14,RSS EXPANDED,UPC-A 1D,UPC-E 1D,UPC/EAN extension,UPC_EAN_EXTENSION
BarcodeFormat.QR_CODE,
qrCodeWidth, //条形码的宽度
qrCodeHeight, //条形码的高度
HINTS);//生成条形码时的一些配置,此项可选
for (int x = 0; x < qrCodeWidth; x++) {
for (int y = 0; y < qrCodeHeight; y++) {
image.setRGB(x, y, (matrix.get(x, y) ? BLACK : WHITE));
}
}
int width = image.getWidth();
int height = image.getHeight();
if (Objects.nonNull(logoSrc) && logoSrc.exists()) {
// 构建绘图对象
Graphics2D g = image.createGraphics();
// 读取Logo图片
BufferedImage logo = ImageIO.read(logoSrc);
// 开始绘制logo图片
g.drawImage(logo, width * 2 / 5, height * 2 / 5, width * 2 / 10, height * 2 / 10, null);
BasicStroke stroke = new BasicStroke(5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
g.setStroke(stroke);// 设置笔画对象
//指定弧度的圆角矩形
RoundRectangle2D.Float round = new RoundRectangle2D.Float(width/5*2, height/5*2, width/5, height/5,20,20);
g.setColor(Color.WHITE);
g.draw(round);// 绘制圆弧矩形
//设置logo 有一道灰色边框
BasicStroke stroke2 = new BasicStroke(1,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
g.setStroke(stroke2);// 设置笔画对象
RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(width/5*2+2, height/5*2+2, width/5-4, height/5-4,20,20);
g.setColor(new Color(128,128,128));
g.draw(round2);// 绘制圆弧矩形
g.dispose();
logo.flush();
}
image.flush();
return ImageIO.write(image, StringUtil.trim(imageFormat, FileType.PNG.getSuffix()), qrCodeSrc);
}
/**
* 生成带Logo的条形码
* @param qrCodeSrc 条形码文件路径
* @param logoSrc Logo文件路径
* @param content 内容
* @param qrCodeWidth 条形码宽度
* @param qrCodeHeight 条形码高度
* @param imageFormat 条形码文件格式
* @return
* @throws WriterException
* @throws IOException
*/
public static boolean createQrCodeAndLogo(String qrCodeSrc, String logoSrc, String content, int qrCodeWidth,
int qrCodeHeight, String imageFormat)
throws WriterException, IOException {
return createQrCodeAndLogo(new File(qrCodeSrc), new File(logoSrc), content, qrCodeWidth, qrCodeHeight, imageFormat);
}
/**
* 读二维码并输出携带的信息
* @param inputStream 输入流
* @return
* @throws IOException
* @throws ReaderException
*/
public static Result readQrCode(InputStream inputStream) throws IOException, ReaderException {
//从输入流中获取字符串信息
BufferedImage image = ImageIO.read(inputStream);
//将图像转换为二进制位图源
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
/*//解码设置编码方式为:utf-8
Map<DecodeHintType, String> hints = new Hashtable<>();
hints.put(DecodeHintType.CHARACTER_SET, CharacterSetECI.UTF8.name()); // 防止中文乱码*/
QRCodeReader reader = new QRCodeReader();
return reader.decode(bitmap, DECODER_HINTS);
}
/**
* 根据url对象进行读取二维码
* @param url URL对象
* @return
* @throws MalformedURLException
* @throws IOException
* @throws ReaderException
*/
public static Result readQrCode(URL url) throws MalformedURLException, IOException, ReaderException {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
return readQrCode(is);
}
/**
* 根据二维码图片路径读取
* @param url 图片路径
* @return
* @throws MalformedURLException
* @throws IOException
* @throws ReaderException
*/
public static Result readQrCodeByUrl(String url) throws MalformedURLException, IOException, ReaderException {
return readQrCode(new URL(url));
}
/**
* 读二维码并输出携带的信息
* @param fileFullPath 文件完整路径
* @return
* @throws IOException
* @throws ReaderException
*/
public static Result readQrCode(String fileFullPath) throws IOException, ReaderException {
return readQrCode(new File(fileFullPath));
}
/**
* 读二维码并输出携带的信息
* @param file 文件
* @return
* @throws IOException
* @throws ReaderException
*/
public static Result readQrCode(File file) throws IOException, ReaderException {
return readQrCode(new FileInputStream(file));
}
public static void main(String... args) throws IOException, WriterException, ReaderException {
String fileFullPath = "/Users/baby/work/tmp/qrcode28.gif";
String logoPath = "/Users/baby/work/tmp/mylogo.jpeg";
String content = "中国人,你啊好!";
// createQrCodeAndLogo(fileFullPath, logoPath, content, 430, 430, "gif");
String content1 = "中华人民共和国";
// content = "WE1231238239128sASDASDSADSDWEWWREWRERWSDFDFSDSDF123123123123213123";
// createQrCode(fileFullPath, content,900, "JPEG");
// Result result = readQrCode(fileFullPath);
// System.err.println("result.toString => " + result.toString());
// String text = result.getText();
// System.err.println("text => " + text);
//
// fileFullPath = "/Users/baby/work/tmp/qrcode29.jpg";
createQrCode(fileFullPath, content,900, "JPEG");
// Result result1 = readQrCode(fileFullPath);
// System.err.println("text1 => " + result1.getText());
//
// fileFullPath = "/Users/baby/work/tmp/qrcode51.jpg"; // 使用QrCode.jar生成的二维码
// Result result2 = readQrCode(fileFullPath);
// System.err.println("text2 => " + result2.getText());
fileFullPath = "C:\\work\\test\\qrcode03.png";
fileFullPath = "/Users/baby/work/upload/qrcode/wx-hello2.png";
Result result3 = readQrCode(fileFullPath);
System.err.println("result3 => " + result3.getText());
String url = "https://images2015.cnblogs.com/blog/755171/201610/755171-20161012154826406-1901968056.png";
Result result4 = readQrCodeByUrl(url);
System.err.println("result4 => " + result4.getText());
content = "{name: '张三', nickname: '张三', age: 23}";
String codeFileName = "C:\\work\\test\\qrcode04.png";
String logoFileName = "C:\\work\\test\\logo.jpg";
codeFileName = "/Users/baby/work/upload/qrcode/qrcode60.jpg";
logoFileName = "/Users/baby/work/tmp/mylogo.jpeg";
// createQrCodeAndLogo(codeFileName, logoFileName, content,
// 430, 430, FileType.PNG.getSuffix());
Result result5 = readQrCode(codeFileName);
System.err.println("result5 => " + result5.getText());
//如果是完整的链接,基本会自动跳转到相应的页面
/*content = "https://www.baidu.com";
codeFileName = "/Users/baby/work/upload/qrcode/qrcode-lianjie.png";
createQrCodeAndLogo(codeFileName, logoFileName, content,
430, 430, FileType.PNG.getSuffix());*/
}
}
The End。