代码来源于https://www.yuque.com/cuckooing大佬工作时开发~

例1

  1. package com.orisdom.utils;
  2. import com.google.zxing.*;
  3. import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
  4. import com.google.zxing.common.BitMatrix;
  5. import com.google.zxing.common.HybridBinarizer;
  6. import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
  7. import javax.imageio.ImageIO;
  8. import java.awt.*;
  9. import java.awt.geom.RoundRectangle2D;
  10. import java.awt.image.BufferedImage;
  11. import java.io.File;
  12. import java.io.OutputStream;
  13. import java.util.Hashtable;
  14. public class QRCodeUtil {
  15. private static final String CHARSET = "utf-8";
  16. private static final String FORMAT_NAME = "JPG";
  17. // 二维码尺寸
  18. private static final int QRCODE_SIZE = 300;
  19. // LOGO宽度
  20. private static final int WIDTH = 60;
  21. // LOGO高度
  22. private static final int HEIGHT = 60;
  23. private static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception {
  24. Hashtable hints = new Hashtable();
  25. hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
  26. hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
  27. hints.put(EncodeHintType.MARGIN, 1);
  28. BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,
  29. hints);
  30. int width = bitMatrix.getWidth();
  31. int height = bitMatrix.getHeight();
  32. BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  33. for (int x = 0; x < width; x++) {
  34. for (int y = 0; y < height; y++) {
  35. image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
  36. }
  37. }
  38. if (imgPath == null || "".equals(imgPath)) {
  39. return image;
  40. }
  41. // 插入图片
  42. QRCodeUtil.insertImage(image, imgPath, needCompress);
  43. return image;
  44. }
  45. private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception {
  46. File file = new File(imgPath);
  47. if (!file.exists()) {
  48. System.err.println("" + imgPath + " 该文件不存在!");
  49. return;
  50. }
  51. Image src = ImageIO.read(new File(imgPath));
  52. int width = src.getWidth(null);
  53. int height = src.getHeight(null);
  54. if (needCompress) { // 压缩LOGO
  55. if (width > WIDTH) {
  56. width = WIDTH;
  57. }
  58. if (height > HEIGHT) {
  59. height = HEIGHT;
  60. }
  61. Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
  62. BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  63. Graphics g = tag.getGraphics();
  64. g.drawImage(image, 0, 0, null); // 绘制缩小后的图
  65. g.dispose();
  66. src = image;
  67. }
  68. // 插入LOGO
  69. Graphics2D graph = source.createGraphics();
  70. int x = (QRCODE_SIZE - width) / 2;
  71. int y = (QRCODE_SIZE - height) / 2;
  72. graph.drawImage(src, x, y, width, height, null);
  73. Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
  74. graph.setStroke(new BasicStroke(3f));
  75. graph.draw(shape);
  76. graph.dispose();
  77. }
  78. public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception {
  79. BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
  80. mkdirs(destPath);
  81. // String file = new Random().nextInt(99999999)+".jpg";
  82. // ImageIO.write(image, FORMAT_NAME, new File(destPath+"/"+file));
  83. ImageIO.write(image, FORMAT_NAME, new File(destPath));
  84. }
  85. public static BufferedImage encode(String content, String imgPath, boolean needCompress) throws Exception {
  86. BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
  87. return image;
  88. }
  89. public static void mkdirs(String destPath) {
  90. File file = new File(destPath);
  91. // 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
  92. if (!file.exists() && !file.isDirectory()) {
  93. file.mkdirs();
  94. }
  95. }
  96. public static void encode(String content, String imgPath, String destPath) throws Exception {
  97. QRCodeUtil.encode(content, imgPath, destPath, false);
  98. }
  99. // 被注释的方法
  100. /*
  101. * public static void encode(String content, String destPath, boolean
  102. * needCompress) throws Exception { QRCodeUtil.encode(content, null, destPath,
  103. * needCompress); }
  104. */
  105. public static void encode(String content, String destPath) throws Exception {
  106. QRCodeUtil.encode(content, null, destPath, false);
  107. }
  108. public static void encode(String content, String imgPath, OutputStream output, boolean needCompress)
  109. throws Exception {
  110. BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
  111. ImageIO.write(image, FORMAT_NAME, output);
  112. }
  113. public static void encode(String content, OutputStream output) throws Exception {
  114. QRCodeUtil.encode(content, null, output, false);
  115. }
  116. public static String decode(File file) throws Exception {
  117. BufferedImage image;
  118. image = ImageIO.read(file);
  119. if (image == null) {
  120. return null;
  121. }
  122. BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
  123. BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
  124. Result result;
  125. Hashtable hints = new Hashtable();
  126. hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
  127. result = new MultiFormatReader().decode(bitmap, hints);
  128. String resultStr = result.getText();
  129. return resultStr;
  130. }
  131. public static String decode(String path) throws Exception {
  132. return QRCodeUtil.decode(new File(path));
  133. }
  134. }

例2

转载于https://www.yuque.com/cuckooing/note/zl4ntw#CkDmy

  1. package com.cuckooing.utils;
  2. import com.google.zxing.BarcodeFormat;
  3. import com.google.zxing.EncodeHintType;
  4. import com.google.zxing.MultiFormatWriter;
  5. import com.google.zxing.common.BitMatrix;
  6. import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
  7. import javax.imageio.ImageIO;
  8. import javax.swing.filechooser.FileSystemView;
  9. import java.awt.image.BufferedImage;
  10. import java.io.File;
  11. import java.util.Date;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14. /**
  15. * Created by Administrator
  16. * 二维码、条形码工具类
  17. */
  18. public class QRBarCodeUtil {
  19. /**
  20. * CODE_WIDTH:二维码宽度,单位像素
  21. * CODE_HEIGHT:二维码高度,单位像素
  22. * FRONT_COLOR:二维码前景色,0x000000 表示黑色
  23. * BACKGROUND_COLOR:二维码背景色,0xFFFFFF 表示白色
  24. * 演示用 16 进制表示,和前端页面 CSS 的取色是一样的,注意前后景颜色应该对比明显,如常见的黑白
  25. */
  26. private static final int CODE_WIDTH = 400;
  27. private static final int CODE_HEIGHT = 400;
  28. private static final int FRONT_COLOR = 0x000000;
  29. private static final int BACKGROUND_COLOR = 0xFFFFFF;
  30. public static void main(String[] args) {
  31. String codeContent1 = "https://www.baidu.com/";
  32. createCodeToFile(codeContent1, new File("D:/images"), "123.png");
  33. }
  34. /**
  35. * 生成二维码 并 保存为图片
  36. */
  37. /**
  38. * @param codeContent :二维码参数内容,如果是一个网页地址,如 https://www.baidu.com/ 则 微信扫一扫会直接进入此地址
  39. * 如果是一些参数,如 1541656080837,则微信扫一扫会直接回显这些参数值
  40. * @param codeImgFileSaveDir :二维码图片保存的目录,如 D:/codes
  41. * @param fileName :二维码图片文件名称,带格式,如 123.png
  42. */
  43. public static void createCodeToFile(String codeContent, File codeImgFileSaveDir, String fileName) {
  44. try {
  45. /** 参数检验*/
  46. if (codeContent == null || "".equals(codeContent)) {
  47. System.out.println("二维码内容为空,不进行操作...");
  48. return;
  49. }
  50. codeContent = codeContent.trim();
  51. if (codeImgFileSaveDir == null || codeImgFileSaveDir.isFile()) {
  52. codeImgFileSaveDir = FileSystemView.getFileSystemView().getHomeDirectory();
  53. System.out.println("二维码图片存在目录为空,默认放在桌面...");
  54. }
  55. if (!codeImgFileSaveDir.exists()) {
  56. codeImgFileSaveDir.mkdirs();
  57. System.out.println("二维码图片存在目录不存在,开始创建...");
  58. }
  59. if (fileName == null || "".equals(fileName)) {
  60. fileName = new Date().getTime() + ".png";
  61. System.out.println("二维码图片文件名为空,随机生成 png 格式图片...");
  62. }
  63. /**com.google.zxing.EncodeHintType:编码提示类型,枚举类型
  64. * EncodeHintType.CHARACTER_SET:设置字符编码类型
  65. * EncodeHintType.ERROR_CORRECTION:设置误差校正
  66. * ErrorCorrectionLevel:误差校正等级,L = ~7% correction、M = ~15% correction、Q = ~25% correction、H = ~30% correction
  67. * 不设置时,默认为 L 等级,等级不一样,生成的图案不同,但扫描的结果是一样的
  68. * EncodeHintType.MARGIN:设置二维码边距,单位像素,值越小,二维码距离四周越近
  69. * */
  70. Map<EncodeHintType, Object> hints = new HashMap();
  71. hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
  72. hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
  73. hints.put(EncodeHintType.MARGIN, 1);
  74. /**
  75. * MultiFormatWriter:多格式写入,这是一个工厂类,里面重载了两个 encode 方法,用于写入条形码或二维码
  76. * encode(String contents,BarcodeFormat format,int width, int height,Map<EncodeHintType,?> hints)
  77. * contents:条形码/二维码内容
  78. * format:编码类型,如 条形码,二维码 等
  79. * width:码的宽度
  80. * height:码的高度
  81. * hints:码内容的编码类型
  82. * BarcodeFormat:枚举该程序包已知的条形码格式,即创建何种码,如 1 维的条形码,2 维的二维码 等
  83. * BitMatrix:位(比特)矩阵或叫2D矩阵,也就是需要的二维码
  84. */
  85. MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
  86. BitMatrix bitMatrix = multiFormatWriter.encode(codeContent, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, hints);
  87. /**java.awt.image.BufferedImage:具有图像数据的可访问缓冲图像,实现了 RenderedImage 接口
  88. * BitMatrix 的 get(int x, int y) 获取比特矩阵内容,指定位置有值,则返回true,将其设置为前景色,否则设置为背景色
  89. * BufferedImage 的 setRGB(int x, int y, int rgb) 方法设置图像像素
  90. * x:像素位置的横坐标,即列
  91. * y:像素位置的纵坐标,即行
  92. * rgb:像素的值,采用 16 进制,如 0xFFFFFF 白色
  93. */
  94. BufferedImage bufferedImage = new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR);
  95. for (int x = 0; x < CODE_WIDTH; x++) {
  96. for (int y = 0; y < CODE_HEIGHT; y++) {
  97. bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? FRONT_COLOR : BACKGROUND_COLOR);
  98. }
  99. }
  100. /**javax.imageio.ImageIO java 扩展的图像IO
  101. * write(RenderedImage im,String formatName,File output)
  102. * im:待写入的图像
  103. * formatName:图像写入的格式
  104. * output:写入的图像文件,文件不存在时会自动创建
  105. *
  106. * 即将保存的二维码图片文件*/
  107. File codeImgFile = new File(codeImgFileSaveDir, fileName);
  108. ImageIO.write(bufferedImage, "png", codeImgFile);
  109. System.out.println("二维码图片生成成功:" + codeImgFile.getPath());
  110. } catch (Exception e) {
  111. e.printStackTrace();
  112. }
  113. }
  114. }

依赖相关

  1. <!--如果是非 web 应用则导入 core 包即可,如果是 web 应用,则 core 与 javase 一起导入。-->
  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. <dependency>
  9. <groupId>com.google.zxing</groupId>
  10. <artifactId>javase</artifactId>
  11. <version>3.3.3</version>
  12. </dependency>

java二维码生成 - 图1