二维码分为两种,一种是 中心有logo的,一种是无logo的,只有二维码内容
这里提供一个工具类,测试类
1.工具类,(工具类中有相关注解,就不解释什么意思了)
package com.jeecg.demo.utils;
import com.swetake.util.Qrcode;
import org.apache.commons.lang3.StringUtils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
/**
* QrcodeUtil
* <p> 生成二维码工具类 包含存放中间图片和不存放中间图片
*
* @author hanyunchuan
* @version 1.0
*/
public class QrcodeUtil {
/**
* 生成二维码(QRCode)有图片
*
* @param content 二维码图片的内容
* @param imgPath 存放生成二维码图片完整的路径
* @param logoPath 二维码图片中间的logo路径
* @param type 生成的图片后缀
*/
public static String createQRCode(String content, String imgPath, String logoPath, int version, String type) {
try {
if (StringUtils.isBlank(imgPath)) {
return "imgPath保存图片的路径未不存在";
} else if (StringUtils.isBlank(logoPath)) {
return "logoPath保存图片的路径未不存在";
} else if (StringUtils.isBlank(content)) {
return "content二维码内容为空";
}
Qrcode qrcodeHandler = new Qrcode();
// 设置二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小
qrcodeHandler.setQrcodeErrorCorrect('M');
// N代表数字,A代表字符a-Z,B代表其他字符
qrcodeHandler.setQrcodeEncodeMode('B');
// 设置设置二维码版本,取值范围1-40,值越大尺寸越大,可存储的信息越大
// 这里对生成二维码内容长度做了判断,如果当前二维码版本不能够存放足够内容的话,会自动+1版本 (下方的 catch (ArrayIndexOutOfBoundsException))
qrcodeHandler.setQrcodeVersion(version);
// 图片尺寸
int imgSize = 67 + 12 * (version - 1);
byte[] contentBytes = content.getBytes("utf-8");
BufferedImage image = new BufferedImage(imgSize, imgSize,
BufferedImage.TYPE_INT_RGB);
Graphics2D gs = image.createGraphics();
gs.setBackground(Color.WHITE);
gs.clearRect(0, 0, imgSize, imgSize);
// 设定图像颜色 > BLACK
gs.setColor(Color.BLACK);
// 设置偏移量 不设置可能导致解析出错
int pixoff = 2;
// 输出内容 > 二维码
if (contentBytes.length > 0 && contentBytes.length < 500) {
boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes);
for (int i = 0; i < codeOut.length; i++) {
for (int j = 0; j < codeOut.length; j++) {
if (codeOut[j][i]) {
gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
}
}
}
} else {
return "QRCode content bytes length =" + contentBytes.length + " not in [ 0,500]";
}
// 实例化一个Image对象。
Image logo = ImageIO.read(new File(logoPath));
int widthLogo = logo.getWidth(null) > image.getWidth() * 3 / 10 ? (image.getWidth() * 3 / 10) :
logo.getWidth(null), heightLogo = logo.getHeight(null) > image.getHeight() * 3 / 10 ?
(image.getHeight() * 3 / 10) : logo.getWidth(null);
/**
* logo放在中心
*/
int x = (image.getWidth() - widthLogo) / 2;
int y = (image.getHeight() - heightLogo) / 2;
gs.drawImage(logo, x, y, widthLogo, heightLogo, null);
gs.dispose();
image.flush();
// 生成二维码QRCode图片
File imgFile = new File(imgPath);
ImageIO.write(image, type, imgFile);
} catch (ArrayIndexOutOfBoundsException ae) {
if (version < 20) {
System.out.print("内容过多提高二维码级别,当前级别:" + version);
createQRCode(content, imgPath, logoPath, version + 1, type);
} else {
ae.printStackTrace();
return "error";
}
} catch (Exception e) {
e.printStackTrace();
return "error";
}
return "success";
}
/**
* 生成二维码(QRCode)无图片
*
* @param content 二维码图片的内容 //生成二维码中要存储的信息
* @param imgPath 存放生成二维码图片完整的路径
* @param type 生成的图片后缀
* @param version 二维码版本号 1 - 20
* @return StatusCode
*/
public static String createQRCode(String content, String imgPath, int version, String type) {
long startTime = System.currentTimeMillis();
System.out.println("startTime-:" + startTime);
try {
Qrcode qrcode = new Qrcode();
qrcode.setQrcodeErrorCorrect('M');//纠错等级(分为L、M、H三个等级)
qrcode.setQrcodeEncodeMode('B');//N代表数字,A代表a-Z,B代表其它字符
qrcode.setQrcodeVersion(version);//版本
//设置一下二维码的像素
int width = 67 + 12 * (qrcode.getQrcodeVersion() - 1);
int height = 67 + 12 * (qrcode.getQrcodeVersion() - 1);
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//绘图
Graphics2D gs = bufferedImage.createGraphics();
gs.setBackground(Color.WHITE);
gs.setColor(Color.BLACK);
gs.clearRect(0, 0, width, height);//清除下画板内容
//设置下偏移量,如果不加偏移量,有时会导致出错。
int pixoff = 2;
byte[] d = new byte[0];
d = content.getBytes("gb2312");
if (d.length > 0 && d.length < 120) {
boolean[][] s = qrcode.calQrcode(d);
for (int i = 0; i < s.length; i++) {
for (int j = 0; j < s.length; j++) {
if (s[j][i]) {
gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
}
}
}
}
gs.dispose();
bufferedImage.flush();
ImageIO.write(bufferedImage, type, new File(imgPath));
} catch (Exception e) {
e.printStackTrace();
return "error";
}
long endTime = System.currentTimeMillis();
System.out.println("endTime-:" + endTime);
System.out.println("用时-:" + (endTime - startTime));
return "success";
}
}
com.swetake.util.Qrcode 类需要下载一个jar包,
这个jar包csdn已存在,我就不上传了.可以搜索一下qrCode.jar,或者去其他地方下载相关jar包.
[注:含图片的二维码生成方法中有二维码自动增加级别,无图片的没有,可以自行添加]
2.测试类:
public static void main(String[] args) {
String content = "https://blog.csdn.net/hyc123123123123";
// 二维码中心有logo
QrcodeUtil.createQRCode(content, "E:\\del\\qrcode有logo.jpg", "E:\\del\\timg.jpg", 4, "png");
// 二维码中心无logo
QrcodeUtil.createQRCode(content, "E:\\del\\qrcode无logo.jpg", 4, "png");
}
测试生成结果:
有logo:
无logo: