Java基于zxing生成二维码矩阵过程解析

 更新时间:2020年09月28日 11:05:04   作者:海绵般汲取  
这篇文章主要介绍了Java基于zxing生成二维码矩阵过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

这个例子需要使用google的开源项目zxing的核心jar包

core-3.2.0.jar

可以百度搜索下载jar文件,也可使用maven添加依赖

<dependency>
      <groupId>com.google.zxing</groupId>
      <artifactId>core</artifactId>
      <version>3.2.0</version>
    </dependency>

下面是将生成的二维码矩阵写入到jpg文件中。

* 生成二维码图片
   * @param dir    存放的目录
   * @param fileName 文件名要以.jpg结尾
   * @param content 这个内容可以是文字或链接
   */
  public static void generateQRCode(String dir, String fileName, String content) {
    //生成二维码的宽高
    int size = 400;
    Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
    // 指定纠错等级
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
    // 指定编码格式
    hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
    // 指定二维码的边距,设置后无效,,设置纠错等级ErrorCorrectionLevel.H为高等级时,无效    //hints.put(EncodeHintType.MARGIN, 1);
    try {
      //encode(String contents, BarcodeFormat format, int width, int height, Map<EncodeHintType, ?> hints)
      BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size, hints);

      //bitMatrix = updateBit(bitMatrix, 20);
      File file1 = new File(dir);
      if (!file1.exists()) {
        file1.mkdirs();
      }

      //将生成的矩阵像素写入到指定文件中,这里是以jpg结尾
      MatrixToImageWriter.writeToStream(bitMatrix, "jpg", new FileOutputStream(dir + "/" + fileName));
      System.out.println("创建成功");
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    } catch (WriterException e) {
      e.printStackTrace();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

上面指定了纠错等级设置有四个值

/** L = ~7% correction */
 L(0x01),
 /** M = ~15% correction */
 M(0x00),
 /** Q = ~25% correction */
 Q(0x03),
 /** H = ~30% correction */
 H(0x02);

指定为L,M这两个等级时,二维码大小会根据其存储的数据量变化,即边距肯能会很大,看下图,

Q,H高等级时,会按照标准格式显示二维码图片。建议使用H等级。

这里生成的二维码留的白色边距有点多,想要适当减小边距,看下图

如果不想边距太大,我们可以将生成的二维码图片进行剪切。新建立一个空的BitMatrix对象来放这个二维码

margin为白色边距的大小

private static BitMatrix updateBit(BitMatrix matrix, int margin) {

    int tempM = margin * 2;

    //left,top,width,height 
    // 0  1  2   3  对应的数组下标
    //这里的width和height是指去除白色边框后的真实的二维码长宽,而不是图片长宽。
    int[] rec = matrix.getEnclosingRectangle(); // 获取二维码图案的属性

    int resWidth = rec[2] + tempM;//真实宽度加左右边距
    int resHeight = rec[3] + tempM;

    BitMatrix resMatrix = new BitMatrix(resWidth, resHeight); // 按照自定义边框生成新的BitMatrix

    resMatrix.clear();
    //从上->下按列进行值得复制,即一列一列的扫描到新的二维矩阵中
    for (int i = margin; i < resWidth - margin; i++) { // 循环,将二维码图案绘制到新的bitMatrix中

      for (int j = margin; j < resHeight - margin; j++) {
        //margin + rec[0]
        if (matrix.get(i - margin + rec[0], j - margin + rec[1])) {
          resMatrix.set(i, j);
        }
      }
    }
    return resMatrix;
  }

生成二维码

这样白色边距就不会太大了,好看多了

后面还有将二维码嵌入到海报,或者其他活动图片上的方法,直接上代码

将二维码放置在图片右下角的位置

public void insertQRCode(BufferedImage zxingImage, String backgroundPath) {
    InputStream dest = null;

    try {
      dest = new FileInputStream(backgroundPath);
      BufferedImage image = ImageIO.read(dest);

      Graphics g = image.getGraphics();

      int leftMargin = image.getWidth() - zxingImage.getWidth() - 10;
      int topMargin = image.getHeight() - zxingImage.getHeight() - 10;
      g.drawImage(zxingImage, leftMargin, topMargin, zxingImage.getWidth(), zxingImage.getHeight(), null);
      ImageIO.write(image, "jpg", new FileOutputStream("D:\\QRCode\\zengmei.jpg"));
      System.out.println("创建成功");
      
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

生成后的结果,图片是本地随便找了一张图片

修改二维码线条颜色,在二维码中插入logo图标等方法

发现修改二维码颜色之后,用微信,qq扫描二维码很难被识别。这个很难受。这里说下怎么改。

修改原理就是,将内容通过new MultiFormatWriter().encode()方法生成二维矩阵后,,

用一个新的BufferedImage对象作为容器给矩阵的两个不同的值设置颜色,有值得为true,没值false,即设置黑白两种颜色

/**
   * 
   * @param onColor 二维码的颜色,即黑白二维码的黑色 :0xFF000000 蓝色 0xFF000055
   * @param offColor 二维码的背景色  如白色:0xFFFFFFFF
   */
  public static void generateOtherQRCode(int onColor, int offColor) {
    String content = "小姐姐最棒啦^_^";
    int size = 200;
    Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
    // 指定纠错等级
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
    // 指定编码格式
    hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
    try {
      BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size, hints);
      BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix,
          new MatrixToImageConfig(onColor, offColor));

      ImageIO.write(image, "png", new FileOutputStream("D:/QRCode/beautiful.png"));
      System.out.println("操作成功");
      
    } catch (IOException e) {
      e.printStackTrace();
    } catch (WriterException e) {
      e.printStackTrace();
    }
  }

重要方法是:MatrixToImageWriter.toBufferedImage

也就是设置颜色,然后返回BufferImage对象

public static BufferedImage toBufferedImage(BitMatrix matrix, MatrixToImageConfig config) {
  int width = matrix.getWidth();
  int height = matrix.getHeight();
  BufferedImage image = new BufferedImage(width, height, config.getBufferedImageColorModel());
  int onColor = config.getPixelOnColor();
  int offColor = config.getPixelOffColor();
  for (int x = 0; x < width; x++) {
   for (int y = 0; y < height; y++) {
    image.setRGB(x, y, matrix.get(x, y) ? onColor : offColor);
   }
  }
  return image;
 }
//imageType , zxing支持的图像类型有三种,黑白颜色的默认为BufferedImage.TYPE_BYTE_BINARY = 12,图像不带透明度alpha  最多是4bit的的图像TYPE_INT_RGB 这个是不带alpha的8bit图像TYPE_INT_ARGB 这个带alpha的8bit图像
java.awt.image.BufferedImage.BufferedImage(int width, int height, int imageType)

开源项目地址

https://github.com/zxing/zxing

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Java数据结构与算法之循环队列的实现

    Java数据结构与算法之循环队列的实现

    循环队列 (Circular Queue) 是一种特殊的队列。循环队列解决了队列出队时需要将所有数据前移一位的问题。本文将带大家详细了解循环队列如何实现,需要的朋友可以参考一下
    2021-12-12
  • Spring中的@Scope注解详细讲解及示例

    Spring中的@Scope注解详细讲解及示例

    这篇文章主要介绍了Spring中的@Scope注解详细讲解及示例,@Scope注解是 Spring IOC 容器中的一个作用域,在 Spring IOC 容器中,他用来配置Bean实例的作用域对象,需要的朋友可以参考下
    2023-11-11
  • 工具类之关于RestTemplateUtil工具类的使用

    工具类之关于RestTemplateUtil工具类的使用

    这篇文章主要介绍了工具类之关于RestTemplateUtil工具类的使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • 解决RestTemplate 的getForEntity调用接口乱码的问题

    解决RestTemplate 的getForEntity调用接口乱码的问题

    这篇文章主要介绍了解决RestTemplate 的getForEntity调用接口乱码的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • SpringBoot实现自定义Redis的连接的流程步骤

    SpringBoot实现自定义Redis的连接的流程步骤

    Spring Boot 自定义 Redis 主要是指在基于 Spring Boot 的应用程序中,当你需要更深入地控制或扩展对 Redis 数据库的操作,而不是仅仅依赖 Spring Data Redis 的默认配置,本文给大家介绍了SpringBoot实现自定义Redis的连接的流程步骤,需要的朋友可以参考下
    2024-09-09
  • Java中的PowerMock使用实践

    Java中的PowerMock使用实践

    这篇文章主要介绍了Java中的PowerMock使用实践,@PrepareForTest和@RunWith是成对出现的,一般@RunWith(PowerMockRunner.class),@PrepareForTest的值是引用的静态方法或私有方法的类,需要的朋友可以参考下
    2023-12-12
  • Java 编程之IO流资料详细整理

    Java 编程之IO流资料详细整理

    这篇文章主要介绍了Java 编程之IO流资料详细整理的相关资料,需要的朋友可以参考下
    2017-02-02
  • SpringBoot web静态资源映射实现步骤详解

    SpringBoot web静态资源映射实现步骤详解

    在springBoot中的静态资源的映射是通过SpringMVC中的resourceHttpRequestHandler来进行实现的。在该请求映射器中默认规定了,SpringBoot会将classPath或者ServletContext下的/static (/public、/resources 或 /META-INF/resources)目录中,存放静态资源
    2022-09-09
  • JavaWeb实现简单查询商品功能

    JavaWeb实现简单查询商品功能

    这篇文章主要为大家详细介绍了JavaWeb实现简单查询商品功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • SpringBoot整合Dubbo+Zookeeper实现RPC调用

    SpringBoot整合Dubbo+Zookeeper实现RPC调用

    这篇文章主要给大家介绍了Spring Boot整合Dubbo+Zookeeper实现RPC调用的步骤详解,文中有详细的代码示例,对我们的学习或工作有一定的帮助,需要的朋友可以参考下
    2023-07-07

最新评论