当前位置: 首页 > news >正文

java生成二维码工具类

`package com.ahsz.uomp.common.util;

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.qrcode.decoder.ErrorCorrectionLevel;
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.imageio.ImageIO;
import java.awt.;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.URLDecoder;
import java.nio.file.Paths;
import java.util.
;
import java.util.List;

/**

  • @program: dict-uomp_git

  • @description: 二维码工具类

  • @author: huang wei

  • @create: 2025-12-11 17:11
    /
    @Slf4j
    public class QrCodeUtil {
    /
    *

    • 默认编码方式
      /
      private static final String DEFAULT_CHARSET = "UTF-8";
      /
      *
    • 默认二维码图片格式
      /
      private static final String DEFAULT_SUBFIX = "png";
      /
      *
    • 生成二维码默认宽度
      /
      private static final int DEFAULT_WIDTH = 260;
      /
      *
    • 生成二维码默认高度
      /
      private static final int DEFAULT_HEIGHT = 300;
      /
      *
    • 默认二维码中间log宽度
      /
      private static final int DEFAULT_LOG_WIDTH = 50;
      /
      *
    • 默认二维码中间log高度
      /
      private static final int DEFAULT_LOG_HEIGHT = 50;
      /
      *
    • log默认路径
      */
      private static final String DEFAULT_LOG_PATH = QrCodeUtil.class.getClassLoader().getResource("uomp-logo.png").getPath();

    /**

    • @Description: 获取base64格式简单二维码
    • @author: hw
    • @date: 2025/12/12 10:20
      /
      public static String getQRCode(String data) {
      BufferedImage bufferedImage = generateQRCode(data,DEFAULT_WIDTH,DEFAULT_HEIGHT);
      return trans2Base64(bufferedImage);
      }
      /
      *
    • @Description: 获取base64格式二维码,带LOGO图标
    • @author: hw
    • @date: 2025/12/12 10:20
      /
      public static String getQRCodeWithLogo(String data) {
      BufferedImage bufferedImage = generateQRCode(data,DEFAULT_WIDTH,DEFAULT_HEIGHT);
      generateQRCodeWithLogo(bufferedImage, DEFAULT_WIDTH, DEFAULT_HEIGHT);
      return trans2Base64(bufferedImage);
      }
      /
      *
    • @Description: 获取base64格式二维码,带底部文字
    • @author: hw
    • @date: 2025/12/12 10:20
      /
      public static String getQRCodeWithText(String data, String text) {
      BufferedImage bufferedImage = generateQRCode(data,DEFAULT_WIDTH,DEFAULT_HEIGHT);
      generateQRCodeWithText(bufferedImage, DEFAULT_WIDTH, DEFAULT_HEIGHT, text);
      return trans2Base64(bufferedImage);
      }
      /
      *
    • @Description: 获取base64格式二维码,带LOGO图标+底部文字
    • @author: hw
    • @date: 2025/12/12 10:21
      */
      public static String getQRCodeWithLogoAndText(String data, String text) {
      BufferedImage bufferedImage = generateQRCode(data,DEFAULT_WIDTH,DEFAULT_HEIGHT);
      generateQRCodeWithLogo(bufferedImage, DEFAULT_WIDTH, DEFAULT_HEIGHT);
      generateQRCodeWithText(bufferedImage, DEFAULT_WIDTH, DEFAULT_HEIGHT, text);
      return trans2Base64(bufferedImage);
      }

    /**

    • @Description: 生成base64格式的二维码
    • @Param:
    • @return:
    • @author: hw
    • @date: 2025/12/12 10:06
      */
      private static String trans2Base64(BufferedImage bufferedImage) {
      if (bufferedImage == null) {
      return null;
      }
      try {
      ByteArrayOutputStream stream = new ByteArrayOutputStream();
      ImageIO.write(bufferedImage, DEFAULT_SUBFIX, stream);
      String base64 = new String(Base64.getEncoder().encode(stream.toByteArray()));
      stream.close();
      return "data:image/"+DEFAULT_SUBFIX+";base64," + base64;
      } catch (Exception e) {
      e.printStackTrace();
      }
      return null;
      }

    /**

    • 生成简单二维码BufferedImage对象

    • @param data 二维码内容(文本/URL/WiFi配置等)

    • @param width 二维码宽度(像素)

    • @param height 二维码高度(像素)

    • @return
      */
      private static BufferedImage generateQRCode(String data, int width, int height) {
      if (StringUtils.isEmpty(data)) {
      return null;
      }
      try {
      //1.设置二维码生成参数
      Map<EncodeHintType, Object> hints = new HashMap<>();
      hints.put(EncodeHintType.CHARACTER_SET, DEFAULT_CHARSET);
      hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
      hints.put(EncodeHintType.MARGIN, 1);

       //2.生成二维码矩阵数据MultiFormatWriter writer = new MultiFormatWriter();BitMatrix bitMatrix = writer.encode(data, BarcodeFormat.QR_CODE, width, height, hints);//3.转换为图像对象BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {image.setRGB(x, y, bitMatrix.get(x, y) ? Color.BLACK.getRGB() : Color.WHITE.getRGB());}}return image;
      

      } catch (Exception e) {
      log.error("生成简单二维码BufferedImage对象异常", e);
      }
      return null;
      }

    /**

    • @Description: 二维码BufferedImage添加logo图片

    • @Param:

    • @return:

    • @author: hw

    • @date: 2025/12/12 16:07
      */
      private static void generateQRCodeWithLogo(BufferedImage bufferedImage, Integer width, Integer height){
      try {
      // LOGO处理
      String logoPath = URLDecoder.decode(DEFAULT_LOG_PATH, "UTF-8");
      File file = new File(logoPath);
      if (file.exists()) {
      Image logoImage = ImageIO.read(file);
      Image image = logoImage.getScaledInstance(DEFAULT_LOG_WIDTH, DEFAULT_LOG_HEIGHT, Image.SCALE_SMOOTH);
      BufferedImage tag = new BufferedImage(DEFAULT_LOG_WIDTH, DEFAULT_LOG_HEIGHT, BufferedImage.TYPE_INT_RGB);
      Graphics g = tag.getGraphics();
      // 绘制缩小后的图
      g.drawImage(image, 0, 0, null);
      g.dispose();

            // 插入LOGOint x = (width - DEFAULT_LOG_WIDTH) / 2;int y = (height - DEFAULT_LOG_HEIGHT) / 2;Graphics2D graph = bufferedImage.createGraphics();graph.drawImage(image, x, y, DEFAULT_LOG_WIDTH, DEFAULT_LOG_HEIGHT, null);Shape shape = new RoundRectangle2D.Float(x, y, DEFAULT_LOG_WIDTH, DEFAULT_LOG_HEIGHT, 6, 6);graph.setStroke(new BasicStroke(3f));graph.draw(shape);graph.dispose();}
      

      } catch (Exception e) {
      log.error("二维码BufferedImage添加logo异常", e);
      }
      }

    /**

    • @Description: 二维码BufferedImage添加底部文字
    • @Param:
    • @return:
    • @author: hw
    • @date: 2025/12/12 16:10
      /
      private static void generateQRCodeWithText(BufferedImage bufferedImage, Integer width, Integer height, String text){
      try {
      // 插入底部文本
      if (!StringUtils.isEmpty(text)) {
      int fontStyle = 1;
      int fontSize = 14;
      // 计算文字开始的位置(居中显示)
      // x开始的位置:(图片宽度-字体大小
      字的个数)/2
      int startX = (width - (fontSize * text.length())) / 2;
      // y开始的位置:图片高度-(图片高度-图片宽度)/2
      // int startY = height - (height - width)/2;
      int startY = height - fontSize;
      Graphics2D graph = bufferedImage.createGraphics();
      graph.setColor(Color.BLUE);
      // 字体风格与字体大小
      graph.setFont(new Font(null, fontStyle, fontSize));
      graph.drawString(text, startX, startY);
      graph.dispose();
      }
      } catch (Exception e) {
      log.error("二维码BufferedImage添加底部文字异常", e);
      }
      }

    /**

    • @Description: 批量生成二维码

    • @Param: batchData 底部文字(text):转成二维码的文本(data)

    • @return:

    • @author: hw

    • @date: 2025/12/11 17:18
      */
      private static List batchGenerateQRCodeWithLogoAndText(Map<String,String> batchData) {
      return batchGenerateQRCodeWithLogoAndText(batchData, DEFAULT_WIDTH, DEFAULT_HEIGHT);
      }
      private static List batchGenerateQRCodeWithLogoAndText(Map<String,String> batchData, int width, int height) {
      //1.设置二维码生成参数
      Map<EncodeHintType, Object> hints = new HashMap<>();
      hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
      hints.put(EncodeHintType.ERROR_CORRECTION, com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.M);
      hints.put(EncodeHintType.MARGIN, 1);

      List bufferedImageList = new ArrayList<>();
      for (String text : batchData.keySet()){
      try {
      //2.生成二维码矩阵数据
      MultiFormatWriter writer = new MultiFormatWriter();
      BitMatrix bitMatrix = writer.encode(batchData.get(text), BarcodeFormat.QR_CODE, width, height, hints);

            //3.转换为图像对象BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {image.setRGB(x, y, bitMatrix.get(x, y) ? Color.BLACK.getRGB() : Color.WHITE.getRGB());}}// 4.写入logogenerateQRCodeWithLogo(image, width, height);// 5.写入文本generateQRCodeWithText(image, width, height, text);bufferedImageList.add(image);} catch (Exception e) {log.error("生成二维码BufferedImage异常: {}", text, e);}
      

      }
      return bufferedImageList;
      }

    /**

    • @Description: 图片导出为PDF
    • @Param:
    • @return:
    • @author: hw
    • @date: 2025/12/15 9:00
      */
      public static void saveImagesToPDF(List bufferedImageList, String outputPath){
      Document document = new Document();
      try {
      PdfWriter.getInstance(document, new FileOutputStream(outputPath));
      document.open();
      for (BufferedImage bufferedImage : bufferedImageList) {
      // 创建PDF图片对象
      try {
      com.itextpdf.text.Image pdfImage = com.itextpdf.text.Image.getInstance(bufferedImage, null);
      pdfImage.setAlignment(com.itextpdf.text.Image.ALIGN_CENTER);
      document.add(pdfImage);
      }catch (Exception e){
      log.error("创建PDF图片对象失败", e);
      }
      }
      } catch (Exception e){
      log.error("图片导出为PDF异常", e);
      } finally {
      document.close();
      }
      }

    public static void main(String[] args) {
    // 生成二维码base64数据
    // String data = "{"msg": "d7572de94b9debc5b4d605697669c4c9","keyNum": 1,"algType": "SM4"}";
    // String text = "校园安防-研发测试-大法师-003";
    // System.out.println(getQRCode(data));
    // System.out.println(getQRCodeWithLogo(data));
    // System.out.println(getQRCodeWithText(data, text));
    // System.out.println(getQRCodeWithLogoAndText(data, text));

     // 批量生成二维码并导出为pdfString path = Paths.get("").toAbsolutePath().toString();String outputPath = path+File.separator+"output.pdf"; // PDF文件的输出路径Map<String,String> map = new HashMap<>();map.put("校园安防-研发测试-大法师-001","{\"msg\": \"d7572de94b9debc5b4d605697669c4c9\",\"keyNum\": 1,\"algType\": \"SM4\"}");map.put("校园安防-研发测试-大法师-002","{\"msg\": \"d7572de94b9debc5b4d605697669c4c9\",\"keyNum\": 1,\"algType\": \"SM4\"}");map.put("校园安防-研发测试-大法师-003","{\"msg\": \"d7572de94b9debc5b4d605697669c4c9\",\"keyNum\": 1,\"algType\": \"SM4\"}");List<BufferedImage> images = batchGenerateQRCodeWithLogoAndText(map);saveImagesToPDF(images, outputPath);System.out.println("PDF文件已保存至:" + outputPath);
    

    }

}
`

http://www.jsqmd.com/news/91985/

相关文章:

  • Higress v2迁移实战:零中断升级的终极方案
  • 腾讯HunyuanCustom开源:多模态视频生成技术重构内容生产范式
  • Apache Pulsar消息过滤终极指南:从入门到精通的完整教程
  • 31、深入了解XHTML+SMIL:创建交互式多媒体文档
  • DeepSeek-Prover-V2终极指南:如何用AI助手轻松搞定数学证明
  • LTX-Video分布式训练终极指南:从入门到生产部署的实战技巧
  • hadoop集群搭建 (超详细) 接入Impala、Hive,AI 大模型的数据底座
  • Wan2.2视频生成模型终极指南:从技术原理到实战部署
  • Fusion Pixel Font:开启像素艺术字体新纪元
  • 终极指南:JoltPhysics球体碰撞边缘问题的完整解决方案
  • MeterSphere内网部署终极指南:3步搞定企业级测试平台搭建
  • 深度对比三种主流文本生成模型的技术特点与性能表现
  • OrcaSlicer终极指南:从入门到精通的高效切片软件使用技巧
  • 河北承德市宽城满族自治县自建房设计公司哪家强?2025最新评测排行榜 + 5 星企业推荐 - 苏木2025
  • Higress网关终极升级指南:3步完成v1到v2的无缝迁移
  • Pose-Search:人体动作智能搜索技术实战指南
  • 分组查询注意力(GQA):Transformer推理优化的工程实践与性能突破
  • 效率革命!Qwen3-14B-MLX-4bit双模式推理重构大模型应用范式
  • 19、如何快速打印、存档20张图片
  • 深度解析Apache Pulsar消息过滤:提升实时数据处理效率的终极指南
  • Higress v2终极迁移宝典:5分钟零中断升级全流程
  • 颠覆性动画生成革命:Wan2.2-Animate-14B如何重塑内容创作生态
  • [Android] 自动点击器Klick_v3.4.0
  • 开源协作新范式:AI驱动的高效项目管理实践
  • Pinia v-model绑定深度解析:从响应式失效到性能优化
  • Intel GPU加速llama.cpp:SYCL后端完整配置与性能调优指南
  • 20ms响应+12亿参数:Liquid AI LFM2-1.2B重塑边缘智能范式
  • 医学影像AI实战:从零构建Python智能诊断系统
  • iOS分页菜单性能优化终极方案:深度解析PageMenu缓存策略与实现
  • Joplin完全指南:5步打造你的专属知识管理系统