生成二维码
This commit is contained in:
parent
c4b6f6a0ba
commit
15ddcaa998
|
@ -0,0 +1,136 @@
|
||||||
|
package com.nu.modules.nuBaseInfo.utils;
|
||||||
|
|
||||||
|
import com.google.zxing.BarcodeFormat;
|
||||||
|
import com.google.zxing.EncodeHintType;
|
||||||
|
import com.google.zxing.common.BitMatrix;
|
||||||
|
import com.google.zxing.qrcode.QRCodeWriter;
|
||||||
|
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.geom.Ellipse2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成带logo的二维码工具类
|
||||||
|
*/
|
||||||
|
public class QRCodeUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工具类入口
|
||||||
|
* @param content 二维码内容,如带参数的网址
|
||||||
|
* @param size 二维码图像尺寸,数值越大尺寸越大
|
||||||
|
* @param margin 二维码边距
|
||||||
|
* @param logoPath Logo文件路径
|
||||||
|
* @param outputPath 输出文件路径
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static void generateQRCodeWithLogo(String content, int size, int margin,
|
||||||
|
String logoPath, String outputPath) throws Exception {
|
||||||
|
// 1. 生成基础二维码
|
||||||
|
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
|
||||||
|
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 高容错
|
||||||
|
hints.put(EncodeHintType.MARGIN, margin);
|
||||||
|
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
|
||||||
|
|
||||||
|
QRCodeWriter qrCodeWriter = new QRCodeWriter();
|
||||||
|
BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, size, size, hints);
|
||||||
|
|
||||||
|
// 创建二维码图像
|
||||||
|
BufferedImage qrImage = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
|
||||||
|
Graphics2D qrGraphics = qrImage.createGraphics();
|
||||||
|
|
||||||
|
// 填充白色背景
|
||||||
|
qrGraphics.setColor(Color.WHITE);
|
||||||
|
qrGraphics.fillRect(0, 0, size, size);
|
||||||
|
|
||||||
|
// 绘制黑色模块
|
||||||
|
qrGraphics.setColor(Color.BLACK);
|
||||||
|
for (int x = 0; x < size; x++) {
|
||||||
|
for (int y = 0; y < size; y++) {
|
||||||
|
if (bitMatrix.get(x, y)) {
|
||||||
|
qrGraphics.fillRect(x, y, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 添加Logo到中心
|
||||||
|
BufferedImage logo = null;
|
||||||
|
try {
|
||||||
|
logo = ImageIO.read(new File(logoPath));
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("无法加载Logo图片: " + e.getMessage());
|
||||||
|
// 如果无法加载Logo,则直接保存二维码
|
||||||
|
qrGraphics.dispose();
|
||||||
|
ImageIO.write(qrImage, "PNG", new File(outputPath));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算Logo尺寸(最大不能超过二维码宽度的25%)
|
||||||
|
int logoSize = Math.min(size / 5, Math.min(logo.getWidth(), logo.getHeight()));
|
||||||
|
int logoX = (size - logoSize) / 2;
|
||||||
|
int logoY = (size - logoSize) / 2;
|
||||||
|
|
||||||
|
// 处理Logo为圆形(可选)
|
||||||
|
if (!logoPath.toLowerCase().endsWith(".png")) {
|
||||||
|
// 对于非透明格式的图片,添加白色背景
|
||||||
|
qrGraphics.setColor(Color.WHITE);
|
||||||
|
qrGraphics.fillRect(logoX - 3, logoY - 3, logoSize + 6, logoSize + 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建圆形Logo
|
||||||
|
BufferedImage circularLogo = createCircularImage(logo, logoSize);
|
||||||
|
|
||||||
|
// 添加Logo到二维码
|
||||||
|
qrGraphics.drawImage(circularLogo, logoX, logoY, null);
|
||||||
|
|
||||||
|
qrGraphics.dispose();
|
||||||
|
|
||||||
|
// 3. 保存最终图像
|
||||||
|
ImageIO.write(qrImage, "PNG", new File(outputPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建圆形Logo图片
|
||||||
|
private static BufferedImage createCircularImage(BufferedImage source, int diameter) {
|
||||||
|
BufferedImage output = new BufferedImage(diameter, diameter, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D g2d = output.createGraphics();
|
||||||
|
|
||||||
|
// 设置圆形剪裁区域
|
||||||
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
Ellipse2D.Double circle = new Ellipse2D.Double(0, 0, diameter, diameter);
|
||||||
|
g2d.setClip(circle);
|
||||||
|
|
||||||
|
// 缩放并绘制Logo
|
||||||
|
Image scaledLogo = source.getScaledInstance(diameter, diameter, Image.SCALE_SMOOTH);
|
||||||
|
g2d.drawImage(scaledLogo, 0, 0, null);
|
||||||
|
|
||||||
|
// 添加白色边框
|
||||||
|
g2d.setClip(null);
|
||||||
|
g2d.setColor(Color.WHITE);
|
||||||
|
g2d.setStroke(new BasicStroke(3));
|
||||||
|
g2d.drawOval(0, 0, diameter, diameter);
|
||||||
|
|
||||||
|
g2d.dispose();
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
// 生成带Logo的二维码
|
||||||
|
generateQRCodeWithLogo(
|
||||||
|
"https://www.focusnu.com/devops", // 二维码内容
|
||||||
|
400, // 图像尺寸
|
||||||
|
5, // 二维码边距
|
||||||
|
"D:\\logo.png", // Logo文件路径
|
||||||
|
"D:\\qr_with_logo.png" // 输出文件路径
|
||||||
|
);
|
||||||
|
System.out.println("带Logo的二维码已生成: qr_with_logo.png");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("二维码生成失败: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue