导入相关的jar包
<!--Qrcode creator-->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
绘制带头像的二维码
public class QrCodeCreator {
/**
* 创建带有Logo的二维码
*
* @param logoUrl logo的url
* @param jumpUrl 跳转的url
* @param params 跳转参数
* @return {@link byte[]}
*/
public static byte[] createLogoQrCode(String logoUrl, String jumpUrl, Map<String, String> params) {
// 1、设置二维码的一些参数
HashMap<EncodeHintType, Object> hints = new HashMap<>(8);
// 1.1设置字符集
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
// 1.2设置容错等级;因为有了容错,在一定范围内可以把二维码p成你喜欢的样式
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
// 1.3设置外边距,二维码与白色区域;(即白色区域)
hints.put(EncodeHintType.MARGIN, 1);
// 2、生成二维码
try {
// 2.1定义BitMatrix对象
BitMatrix bitMatrix = new MultiFormatWriter().encode(RequestUrlBuilder.buildRequestUrl(jumpUrl, params), BarcodeFormat.QR_CODE, GlobalConstant.QRCORD_WIDTH, GlobalConstant.QRCORD_HEIGHT, hints);
//2、获取二维码宽高
int codeWidth = bitMatrix.getWidth();
int codeHeight = bitMatrix.getHeight();
//3、将二维码放入缓冲流
BufferedImage image = new BufferedImage(codeWidth, codeHeight, BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < codeWidth; i++) {
for (int j = 0; j < codeHeight; j++) {
//4、循环将二维码内容定入图片
image.setRGB(i, j, bitMatrix.get(i, j) ? GlobalConstant.BLACK : GlobalConstant.WHITE);
}
}
BufferedImage logoImage = null;
try {
URL url = new URL(logoUrl);
logoImage = ImageIO.read(url);
// 2.4在二维码中添加logo
} catch (Exception e) {
e.printStackTrace();
}
return addLogo(image, logoImage);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 添加logo
*
* @param logoImage 标志形象
* @param qrcodeImage qrcode形象
* @return {@link byte[]}
*/
private static byte[] addLogo(BufferedImage qrcodeImage, BufferedImage logoImage) {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
if (logoImage == null) {
Thumbnails.of(qrcodeImage).scale(1).outputFormat("jpg").toOutputStream(outputStream);
return outputStream.toByteArray();
}
// 3、计算图片放置的位置
int x = (qrcodeImage.getWidth() - GlobalConstant.LOGO_WIDTH) / 2;
int y = (qrcodeImage.getHeight() - GlobalConstant.LOGO_HEIGHT) / 2;
//白底与头像的距离
int logoBorder = 10;
//画一个透明的外圈
BufferedImage whiteBase = new BufferedImage(GlobalConstant.LOGO_WIDTH, GlobalConstant.LOGO_HEIGHT, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = whiteBase.createGraphics();
//设置颜色
graphics.setColor(Color.WHITE);
//填充
graphics.fillRect(0, 0, whiteBase.getWidth(), whiteBase.getHeight());
graphics.drawImage(whiteBase, 0, 0, GlobalConstant.LOGO_WIDTH, GlobalConstant.LOGO_HEIGHT, null);
graphics.dispose();
//绘画白底,设置圆角
Graphics2D graphics2 = qrcodeImage.createGraphics();
graphics2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int padding = logoBorder / 2;
graphics2.setClip(new RoundRectangle2D.Double(x - padding, x - padding, GlobalConstant.LOGO_WIDTH, GlobalConstant.LOGO_HEIGHT, 15, 15));
graphics2.drawImage(whiteBase, x - padding, x - padding, GlobalConstant.LOGO_WIDTH, GlobalConstant.LOGO_HEIGHT, null);
graphics2.dispose();
// 1、读取二维码图片,并构建绘图对象
Graphics2D graph = qrcodeImage.createGraphics();
graph.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graph.setClip(new RoundRectangle2D.Double(x, y, GlobalConstant.LOGO_WIDTH - logoBorder, GlobalConstant.LOGO_HEIGHT - logoBorder, 15, 15));
// 4、绘制图片
graph.drawImage(logoImage, x, y, GlobalConstant.LOGO_WIDTH - logoBorder, GlobalConstant.LOGO_HEIGHT - logoBorder, null);
graph.dispose();
Thumbnails.of(qrcodeImage).scale(1).outputFormat("jpg").toOutputStream(outputStream);
return outputStream.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
RequestUrlBuilder.java
public class RequestUrlBuilder {
public static String buildRequestUrl(String url, Map<String, String> params) {
if (params == null || params.isEmpty()) {
return url;
}
StringBuilder builder = new StringBuilder();
// 如果以/结果,去掉/
if (url.endsWith("/")) {
builder.append(url, 0, url.length() - 1);
} else {
builder.append(url);
}
if (!(url.endsWith("?") || url.endsWith("&"))) {
if (url.contains("?")) {
builder.append("&");
} else {
builder.append("?");
}
}
return builder.append(buildQuery(params)).toString();
}
}
测试代码:
@Test
public void drawQrcode() {
byte[] bytes = QrCodeCreator.createLogoQrCode("https://liaomr.com/img/photo.jpg", "https://liaomr.com/", null);
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes)) {
Thumbnails.of(byteArrayInputStream).scale(1).toFile("D:\\qrcode.jpg");
} catch (IOException e) {
e.printStackTrace();
}
}
最终结果: