二维码称为QR Code,QR全称Quick Response。下面直接上代码,看看在java语言里如何生成二维码的吧。

首先,在pom文件中引入zxing的两个架包:
  1. <!--二维码生成架包引用-->
  2. <!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
  3. <dependency>
  4. <groupId>com.google.zxing</groupId>
  5. <artifactId>core</artifactId>
  6. <version>3.3.3</version>
  7. </dependency>
  8. <!-- https://mvnrepository.com/artifact/com.google.zxing/javase -->
  9. <dependency>
  10. <groupId>com.google.zxing</groupId>
  11. <artifactId>javase</artifactId>
  12. <version>3.3.3</version>
  13. </dependency>

接着编写工具类,进行测试;
  1. import java.awt.BasicStroke;
  2. import java.awt.Graphics;
  3. import java.awt.Graphics2D;
  4. import java.awt.Image;
  5. import java.awt.Shape;
  6. import java.awt.geom.RoundRectangle2D;
  7. import java.awt.image.BufferedImage;
  8. import java.io.File;
  9. import java.util.Hashtable;
  10. import javax.imageio.ImageIO;
  11. import com.google.zxing.BarcodeFormat;
  12. import com.google.zxing.BinaryBitmap;
  13. import com.google.zxing.DecodeHintType;
  14. import com.google.zxing.EncodeHintType;
  15. import com.google.zxing.MultiFormatReader;
  16. import com.google.zxing.MultiFormatWriter;
  17. import com.google.zxing.Result;
  18. import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
  19. import com.google.zxing.common.BitMatrix;
  20. import com.google.zxing.common.HybridBinarizer;
  21. import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
  22. /**
  23. * 二维码生成解析工具类
  24. * @author 程就人生
  25. * @date 2019年7月27日
  26. * @Description
  27. *
  28. */
  29. public class QRCodeUtil {
  30. //编码格式,采用utf-8
  31. private static final String UNICODE = "utf-8";
  32. //图片格式
  33. private static final String FORMAT = "JPG";
  34. //二维码宽度,单位:像素pixels
  35. private static final int QRCODE_WIDTH = 300;
  36. //二维码高度,单位:像素pixels
  37. private static final int QRCODE_HEIGHT = 300;
  38. //LOGO宽度,单位:像素pixels
  39. private static final int LOGO_WIDTH = 100;
  40. //LOGO高度,单位:像素pixels
  41. private static final int LOGO_HEIGHT = 100;
  42. /**
  43. * 生成二维码图片
  44. * @param content 二维码内容
  45. * @param logoPath 图片地址
  46. * @param needCompress 是否压缩
  47. * @return
  48. * @throws Exception
  49. */
  50. private static BufferedImage createImage(String content, String logoPath, boolean needCompress) throws Exception {
  51. Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
  52. hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
  53. hints.put(EncodeHintType.CHARACTER_SET, UNICODE);
  54. hints.put(EncodeHintType.MARGIN, 1);
  55. BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_WIDTH, QRCODE_HEIGHT,
  56. hints);
  57. int width = bitMatrix.getWidth();
  58. int height = bitMatrix.getHeight();
  59. BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  60. for (int x = 0; x < width; x++) {
  61. for (int y = 0; y < height; y++) {
  62. image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
  63. }
  64. }
  65. if (logoPath == null || "".equals(logoPath)) {
  66. return image;
  67. }
  68. // 插入图片
  69. QRCodeUtil.insertImage(image, logoPath, needCompress);
  70. return image;
  71. }
  72. /**
  73. * 插入LOGO
  74. * @param source 二维码图片
  75. * @param logoPath LOGO图片地址
  76. * @param needCompress 是否压缩
  77. * @throws Exception
  78. */
  79. private static void insertImage(BufferedImage source, String logoPath, boolean needCompress) throws Exception {
  80. File file = new File(logoPath);
  81. if (!file.exists()) {
  82. throw new Exception("logo file not found.");
  83. }
  84. Image src = ImageIO.read(new File(logoPath));
  85. int width = src.getWidth(null);
  86. int height = src.getHeight(null);
  87. if (needCompress) { // 压缩LOGO
  88. if (width > LOGO_WIDTH) {
  89. width = LOGO_WIDTH;
  90. }
  91. if (height > LOGO_HEIGHT) {
  92. height = LOGO_HEIGHT;
  93. }
  94. Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
  95. BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  96. Graphics g = tag.getGraphics();
  97. g.drawImage(image, 0, 0, null); // 绘制缩小后的图
  98. g.dispose();
  99. src = image;
  100. }
  101. // 插入LOGO
  102. Graphics2D graph = source.createGraphics();
  103. int x = (QRCODE_WIDTH - width) / 2;
  104. int y = (QRCODE_HEIGHT - height) / 2;
  105. graph.drawImage(src, x, y, width, height, null);
  106. Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
  107. graph.setStroke(new BasicStroke(3f));
  108. graph.draw(shape);
  109. graph.dispose();
  110. }
  111. /**
  112. * 生成二维码(内嵌LOGO)
  113. * 调用者指定二维码文件名
  114. * @param content 二维码的内容
  115. * @param logoPath 中间图片地址
  116. * @param destPath 存储路径
  117. * @param fileName 文件名称
  118. * @param needCompress 是否压缩
  119. * @return
  120. * @throws Exception
  121. */
  122. public static String encode(String content, String logoPath, String destPath, String fileName, boolean needCompress) throws Exception {
  123. BufferedImage image = QRCodeUtil.createImage(content, logoPath, needCompress);
  124. mkdirs(destPath);
  125. //文件名称通过传递
  126. fileName = fileName.substring(0, fileName.indexOf(".")>0?fileName.indexOf("."):fileName.length())
  127. + "." + FORMAT.toLowerCase();
  128. ImageIO.write(image, FORMAT, new File(destPath + "/" + fileName));
  129. return fileName;
  130. }
  131. /**
  132. * 创建文件夹, mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
  133. * @param destPath
  134. */
  135. public static void mkdirs(String destPath) {
  136. File file = new File(destPath);
  137. if (!file.exists() && !file.isDirectory()) {
  138. file.mkdirs();
  139. }
  140. }
  141. /**
  142. * 解析二维码
  143. * @param path 二维码图片路径
  144. * @return String 二维码内容
  145. * @throws Exception
  146. */
  147. public static String decode(String path) throws Exception {
  148. File file = new File(path);
  149. BufferedImage image = ImageIO.read(file);
  150. if (image == null) {
  151. return null;
  152. }
  153. BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
  154. BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
  155. Result result;
  156. Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
  157. hints.put(DecodeHintType.CHARACTER_SET, UNICODE);
  158. result = new MultiFormatReader().decode(bitmap, hints);
  159. return result.getText();
  160. }
  161. /**
  162. * 测试
  163. * @param args
  164. * @throws Exception
  165. */
  166. public static void main(String[] args) throws Exception {
  167. String text = "http://localhost:8001/login/aaa?bbb=ccc";
  168. //不含Logo
  169. QRCodeUtil.encode(text, null, "D:\\cc\\", "qrcode", true);
  170. //含Logo,指定二维码图片名
  171. QRCodeUtil.encode(text, "D:\\cloudfish\\app\\aa.jpg", "d:\\cc\\", "qrcode1", true);
  172. System.out.println(QRCodeUtil.decode("d:\\cc\\qrcode1.jpg"));
  173. }
  174. }

最后,测试结果如下:

【20200201】SpringBoot   ZXing - 图1
图-1

二维码生成技术学习资料: https://www.aliyun.com/ss/?k=二维码生成 https://yq.aliyun.com/articles/239405?spm=5176.10695662.1996646101.searchclickresult.4b6825c7YBvZu6 https://yq.aliyun.com/articles/131683?spm=5176.10695662.1996646101.searchclickresult.4b6825c7YBvZu6 http://code.google.com/p/zxing/ 开源库api文档:https://zxing.github.io/zxing/apidocs/