开发中遇到的问题&解决方案(八)

178 阅读2分钟

「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战

前言

以前的一个老项目里使用过ZXing进行会员和门店二维码的生成操作,当时出现过Java版本升级后不兼容的问题,很是麻烦,于是替换成了hutool里的二维码生成,下面我们来看看具体的实现。

一.带Logo的二维码生成的原理,绘制一个自定义长宽的底图,当然也可以使用一张图片作为底图,然后获取带Logo的本地图片,将Logo图片‘放到’底图上,再将整个图片以流都形式输出

二.具体的实现 1.生成二维码到文件,这种形式很常用

public static File generate(String content, int width, int height, File targetFile) {
   //进行图片绘制
   final BufferedImage image = generate(content, width, height);
   
   ImgUtil.write(image, targetFile);
   return targetFile;
}

1)对图片生成代码部分进行解读

public static BufferedImage generate(String content, BarcodeFormat format, QrConfig config) {
   //先进行将文本内容编码为条形码或二维码
   final BitMatrix bitMatrix = encode(content, format, config);
   //将BitMatrix转BufferedImage 这里转为BufferedImage是为了后面能够拿到Logo的长和宽
   final BufferedImage image = toImage(bitMatrix, config.foreColor, config.backColor);
   final Image logoImg = config.img;
   if (null != logoImg && BarcodeFormat.QR_CODE == format) {
      // 二维码贴图长和宽获取 
      final int qrWidth = image.getWidth();
      final int qrHeight = image.getHeight();
      int width;
      int height;
      // 按照最短的边做比例缩放 
      if (qrWidth < qrHeight) {
         width = qrWidth / config.ratio;
         height = logoImg.getHeight(null) * width / logoImg.getWidth(null);
      } else {
         height = qrHeight / config.ratio;
         width = logoImg.getWidth(null) * height / logoImg.getHeight(null);
      }
      Img.from(image).pressImage(//
       // 圆角处理,不处理的话 Logo在底图中央就看起来很怪异 
            Img.from(logoImg).round(0.3).getImg(),
            new Rectangle(width, height), 
      );
   }
   return image;
}
  1. 生成带Logo图片的Base64 编码格式的二维码,以 String 形式返回,这种不是很常用
//生成图片的主要代码
final BufferedImage img = generate(content, qrConfig);
//将图片对象转换为Base64的Data URI形式
public static String toBase64DataUri(Image image, String imageType) {
  return URLUtil.getDataUri(
        "image/" + imageType, "base64",
        toBase64(image, imageType));
}

3.还有返回BufferedImage和BitMatrix的方法,可以由我们去自行去处理,不是很常用,或者目前的业务还没有使用到,感兴趣的小伙伴可以试试。

小结

hutool里不管是对于FTP还是二维码的生成,我们都可以看到,并没有将方法固定,而且同时提供了一些额外的方法,供我们能够自定义去处理,这点对于遇到业务复杂的小伙伴十分友好。