package com.project.common.utils.qrcode; import com.google.zxing.*; import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.common.HybridBinarizer; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import javax.imageio.ImageIO; import java.awt.*; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; public class QRCodeUtil { private static final String CHARSET = "utf-8"; private static final String IMG_FORMAT_NAME = "PNG"; private static final Integer QR_CODE_SIZE = 800; private static final Integer WIDTH = 200; private static final Integer HEIGHT = 200; private static BufferedImage createImage(String content, String imgPath, Boolean needCompress) throws WriterException, IOException { Hashtable ht = new Hashtable(); ht.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); ht.put(EncodeHintType.CHARACTER_SET, CHARSET); ht.put(EncodeHintType.MARGIN, 1); BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, ht); int height = bitMatrix.getHeight(); int width = bitMatrix.getWidth(); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { image.setRGB(i, j, bitMatrix.get(i,j) ? 0xFF000000 : 0xFFFFFFFF); } } if (imgPath == null || "".equals(imgPath)) { return image; } QRCodeUtil.insertImg(image, imgPath, needCompress); return image; } private static void insertImg(BufferedImage source, String imgPath, Boolean needCompress) throws IOException { File file = new File(imgPath); if (!file.exists()) { System.err.println("" + imgPath + " 该文件不存在!"); throw new FileNotFoundException(); } Image src = ImageIO.read(file); int width = src.getWidth(null); int height = src.getHeight(null); if (needCompress) { width = WIDTH; height = HEIGHT; Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH); BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = img.createGraphics(); g.dispose(); src = image; } Graphics2D graph = source.createGraphics(); int x = (QR_CODE_SIZE - width) / 2; int y = (QR_CODE_SIZE - height) / 2; graph.drawImage(src, x, y, width, height, null); Shape shape = new RoundRectangle2D.Float(x, y, width, height, 6, 6); graph.setStroke(new BasicStroke(3f)); graph.draw(shape); graph.dispose(); } public static void encode(String content, String imgPath, String destPath, Boolean needCompress) throws IOException, WriterException, ClassNotFoundException { BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress); mkdir(destPath); ImageIO.write(image, IMG_FORMAT_NAME, new File(destPath)); } public static BufferedImage encode(String content, String imgPath, Boolean needCompress) throws IOException, WriterException, ClassNotFoundException { BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress); return image; } public static void encode(String content, String imgPath, OutputStream outputStream, Boolean needCompress) throws IOException, WriterException, ClassNotFoundException { BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress); ImageIO.write(image, IMG_FORMAT_NAME, outputStream); } public static void encode(String content, String destPath) throws ClassNotFoundException, IOException, WriterException { QRCodeUtil.encode(content, null, destPath, false); } public static void encode(String content, OutputStream outputStream) throws ClassNotFoundException, IOException, WriterException { QRCodeUtil.encode(content, null, outputStream, false); } public static String decode(File file) throws IOException, NotFoundException { BufferedImage image; image = ImageIO.read(file); if (image == null) { throw new IOException(); } BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); Result result; Hashtable ht = new Hashtable(); ht.put(DecodeHintType.CHARACTER_SET, CHARSET); result = new MultiFormatReader().decode(bitmap, ht); return result.getText(); } public static String decode(String path) throws IOException, NotFoundException { return QRCodeUtil.decode(new File(path)); } private static void mkdir(String destPath) { File file = new File(destPath); if (!file.exists() && !file.isDirectory()) { file.mkdirs(); } } //二维码图上带字 public static void contextLoads2(String content, String name, String filePathStr) { int qrCodeWidth = 350; int qrCodeHeight = 350; int textPadding = 2; // 文本与二维码之间的间距 int textSize = 10; // 文本字体大小 int totalHeight = 380; try { // 生成二维码的BitMatrix BitMatrix bitMatrix = generateQRCode(content, qrCodeWidth, qrCodeHeight); // 将BitMatrix转换为BufferedImage BufferedImage qrCodeImage = MatrixToImageWriter.toBufferedImage(bitMatrix); // 创建一个新的BufferedImage来容纳二维码和文本 BufferedImage combinedImage = new BufferedImage( qrCodeWidth, totalHeight, BufferedImage.TYPE_INT_RGB); // 绘制二维码到新的BufferedImage上 Graphics2D g2d = combinedImage.createGraphics(); g2d.setColor(Color.WHITE); g2d.fillRect(0, 0, qrCodeWidth, totalHeight); g2d.drawImage(qrCodeImage, -5, -10,360,360, null); // 绘制文本到图片下方 Font font = new Font("Black", Font.BOLD, 20); FontMetrics metrics = g2d.getFontMetrics(font); int textX = (qrCodeWidth - metrics.stringWidth("沈丘惠企执法")) / 2; // 设置文本样式 g2d.setFont(font); g2d.setColor(Color.BLACK); // 文本颜色 g2d.drawString("沈丘惠企执法", textX, 330); Font font1 = new Font("Serif", Font.PLAIN, 15); FontMetrics metrics1 = g2d.getFontMetrics(font1); int textX1 = (360 - metrics1.stringWidth(name)) / 2; g2d.setFont(font1); g2d.setColor(Color.BLACK); // 文本颜色 g2d.drawString(name, textX1, 355); g2d.dispose(); // 指定存储图片的路径 Path filePath = Paths.get(filePathStr); // 确保文件路径的父目录存在 filePath.getParent().toFile().mkdirs(); // 保存图片到文件 ImageIO.write(combinedImage, "PNG", filePath.toFile()); System.out.println("QR Code with text has been generated: " + filePath.toAbsolutePath()); } catch (WriterException | IOException e) { e.printStackTrace(); } } private static BitMatrix generateQRCode(String text, int width, int height) throws WriterException { Map hints = new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); return new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints); } }