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

作者:海绵般汲取 时间:2023-11-23 06:04:06 

这个例子需要使用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等级。

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

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

如果不想边距太大,我们可以将生成的二维码图片进行剪切。新建立一个空的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;
 }

生成二维码

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

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

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

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


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();
   }
 }

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

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

修改二维码线条颜色,在二维码中插入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

来源:https://www.cnblogs.com/gne-hwz/p/9445466.html

标签:java,zxing,二维码
0
投稿

猜你喜欢

  • 分享Java常用开发编辑器工具

    2023-11-06 07:35:37
  • Java基于socket实现简易聊天室实例

    2021-10-30 00:24:56
  • SpringMVC的执行流程及组件详解

    2021-06-17 23:29:21
  • java ReentrantLock条件锁实现原理示例详解

    2023-12-12 02:36:13
  • 一篇带你解析入门LongAdder源码

    2023-11-28 20:17:52
  • 实例解析Java中的构造器初始化

    2022-11-22 07:42:27
  • Android利用RenderScript实现毛玻璃模糊效果示例

    2021-05-26 02:32:07
  • Android开发之Wifi基础教程

    2023-04-07 13:10:50
  • 关于JWT之token令牌认证登录

    2022-03-16 07:32:58
  • Android中实现GPS定位的简单例子

    2021-11-24 21:01:25
  • Android 中使用RadioGroup和Fragment实现底部导航栏的功能

    2022-07-17 16:11:04
  • Java mybatis 开发自定义插件

    2022-11-26 03:29:24
  • Jackson的用法实例分析

    2021-11-13 09:13:40
  • Java 随机生成验证码(支持大小写字母、数字、随机字体)的实例

    2023-11-25 00:35:38
  • 详解Flutter中key的正确使用方式

    2021-11-05 04:31:02
  • java调用百度的接口获取起-止位置的距离

    2023-08-11 17:14:27
  • 实例详解C#正则表达式

    2023-06-23 00:03:03
  • Android 应用Crash 后自动重启的方法小结

    2021-06-10 11:34:43
  • spring强行注入和引用实例解析

    2021-11-23 23:26:19
  • OpenGL Shader实现光照发光体特效

    2022-03-16 18:51:50
  • asp之家 软件编程 m.aspxhome.com