QRCodeUtils.java 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package com.zhjq.utils;
  2. import com.google.zxing.BarcodeFormat;
  3. import com.google.zxing.EncodeHintType;
  4. import com.google.zxing.MultiFormatWriter;
  5. import com.google.zxing.WriterException;
  6. import com.google.zxing.common.BitMatrix;
  7. import com.google.zxing.qrcode.QRCodeWriter;
  8. import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
  9. import javax.imageio.ImageIO;
  10. import java.awt.*;
  11. import java.awt.image.BufferedImage;
  12. import java.io.ByteArrayOutputStream;
  13. import java.io.IOException;
  14. import java.util.HashMap;
  15. import java.util.Map;
  16. public class QRCodeUtils {
  17. /**
  18. * 生成二维码
  19. *
  20. * @param content 二维码的内容
  21. * @return BitMatrix对象
  22. */
  23. public static BitMatrix createCode(String content) throws IOException {
  24. //二维码的宽高
  25. int width = 200;
  26. int height = 200;
  27. //其他参数,如字符集编码
  28. Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
  29. hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
  30. //容错级别为H
  31. hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
  32. //白边的宽度,可取0~4
  33. hints.put(EncodeHintType.MARGIN, 0);
  34. BitMatrix bitMatrix = null;
  35. try {
  36. //生成矩阵,因为我的业务场景传来的是编码之后的URL,所以先解码
  37. bitMatrix = new MultiFormatWriter().encode(content,
  38. BarcodeFormat.QR_CODE, width, height, hints);
  39. //bitMatrix = deleteWhite(bitMatrix);
  40. } catch (WriterException e) {
  41. e.printStackTrace();
  42. }
  43. return bitMatrix;
  44. }
  45. /**
  46. * 生成带有底部文字的二维码
  47. *
  48. * @param content 二维码的内容
  49. * @param text 底部文字
  50. * @throws IOException
  51. */
  52. public static byte[] createCodeWithText(String content, String text) throws IOException {
  53. // 二维码的宽高
  54. int width = 300;
  55. int height = 300;
  56. // 其他参数,如字符集编码
  57. Map<EncodeHintType, Object> hints = new HashMap<>();
  58. hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
  59. hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
  60. hints.put(EncodeHintType.MARGIN, 0);
  61. BitMatrix bitMatrix = null;
  62. try {
  63. // 生成二维码矩阵
  64. QRCodeWriter writer = new QRCodeWriter();
  65. bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
  66. } catch (WriterException e) {
  67. e.printStackTrace();
  68. }
  69. // 创建图像并绘制二维码
  70. int imgWidth = width;
  71. int imgHeight = height + 30; // 增加额外空间用于文本
  72. BufferedImage image = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
  73. Graphics2D graphics = image.createGraphics();
  74. // 设置背景色
  75. graphics.setColor(Color.WHITE);
  76. graphics.fillRect(0, 0, imgWidth, imgHeight);
  77. // 绘制二维码
  78. graphics.setColor(Color.BLACK);
  79. for (int x = 0; x < width; x++) {
  80. for (int y = 0; y < height; y++) {
  81. if (bitMatrix.get(x, y)) {
  82. graphics.fillRect(x, y, 1, 1);
  83. }
  84. }
  85. }
  86. // 添加底部文字,使用合适的字体
  87. graphics.setColor(Color.BLACK);
  88. // 使用支持中文的字体
  89. Font font = new Font("Microsoft YaHei", Font.BOLD, 16);
  90. graphics.setFont(font);
  91. FontMetrics metrics = graphics.getFontMetrics(font);
  92. int textWidth = metrics.stringWidth(text);
  93. // 在底部居中绘制文本
  94. graphics.drawString(text, (imgWidth - textWidth) / 2, height + 20);
  95. graphics.dispose();
  96. // 保存图像
  97. try {
  98. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  99. // ImageIO.write(image, "png", new File(filePath));
  100. ImageIO.write(image, "png", outputStream);
  101. return outputStream.toByteArray();
  102. } catch (IOException e) {
  103. e.printStackTrace();
  104. }
  105. return null;
  106. }
  107. /**
  108. * 删除生成的二维码周围的白边,根据审美决定是否删除
  109. *
  110. * @param matrix BitMatrix对象
  111. * @return BitMatrix对象
  112. */
  113. private static BitMatrix deleteWhite(BitMatrix matrix) {
  114. int[] rec = matrix.getEnclosingRectangle();
  115. int resWidth = rec[2] + 1;
  116. int resHeight = rec[3] + 1;
  117. BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
  118. resMatrix.clear();
  119. for (int i = 0; i < resWidth; i++) {
  120. for (int j = 0; j < resHeight; j++) {
  121. if (matrix.get(i + rec[0], j + rec[1]))
  122. resMatrix.set(i, j);
  123. }
  124. }
  125. return resMatrix;
  126. }
  127. }