package com.ruoyi.common.utils; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.client.j2se.MatrixToImageWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * 二维码生成工具类 * * @author ruoyi */ public class QRCodeUtils { private static final Logger log = LoggerFactory.getLogger(QRCodeUtils.class); private static final int WIDTH = 300; private static final int HEIGHT = 300; private static final String FORMAT = "png"; /** * 生成二维码到文件 * * @param content 二维码内容 * @param filePath 文件路径 * @return 是否生成成功 */ public static boolean generateQRCodeToFile(String content, String filePath) { try { Map hints = new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); hints.put(EncodeHintType.MARGIN, 1); BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints); File file = new File(filePath); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } MatrixToImageWriter.writeToFile(bitMatrix, FORMAT, file); return true; } catch (Exception e) { log.error("生成二维码失败: {}", e.getMessage()); return false; } } /** * 生成二维码到字节数组 * * @param content 二维码内容 * @return 字节数组 */ public static byte[] generateQRCodeToBytes(String content) { try { Map hints = new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); hints.put(EncodeHintType.MARGIN, 1); BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints); BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(image, FORMAT, baos); return baos.toByteArray(); } catch (Exception e) { log.error("生成二维码失败: {}", e.getMessage()); return null; } } /** * 生成Base64编码的二维码 * * @param content 二维码内容 * @return Base64编码的二维码 */ public static String generateQRCodeToBase64(String content) { byte[] bytes = generateQRCodeToBytes(content); if (bytes != null) { return "data:image/png;base64," + java.util.Base64.getEncoder().encodeToString(bytes); } return null; } /** * 生成带车牌号的Base64编码二维码 * * @param content 二维码内容 * @param vehicleNo 车牌号 * @return Base64编码的二维码 */ public static String generateQRCodeWithVehicleNoToBase64(String content, String vehicleNo) { try { Map hints = new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); hints.put(EncodeHintType.MARGIN, 1); BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints); BufferedImage qrImage = MatrixToImageWriter.toBufferedImage(bitMatrix); // 创建带文字的图片 int textHeight = 40; // 文字区域高度 int totalHeight = HEIGHT + textHeight; BufferedImage finalImage = new BufferedImage(WIDTH, totalHeight, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = finalImage.createGraphics(); // 设置背景为白色 g2d.setColor(Color.WHITE); g2d.fillRect(0, 0, WIDTH, totalHeight); // 绘制二维码 g2d.drawImage(qrImage, 0, 0, null); // 绘制车牌号文字 g2d.setColor(Color.BLACK); g2d.setFont(new Font("微软雅黑", Font.BOLD, 16)); FontMetrics fm = g2d.getFontMetrics(); int textWidth = fm.stringWidth(vehicleNo); int x = (WIDTH - textWidth) / 2; int y = HEIGHT + (textHeight + fm.getAscent()) / 2; g2d.drawString(vehicleNo, x, y); g2d.dispose(); // 转换为Base64 ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(finalImage, FORMAT, baos); return "data:image/png;base64," + java.util.Base64.getEncoder().encodeToString(baos.toByteArray()); } catch (Exception e) { log.error("生成带车牌号的二维码失败: {}", e.getMessage()); return null; } } }