2021SC@SDUSC Zxing开源代码(三)编码思路及代码分析

发布时间:2022-07-03 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了2021SC@SDUSC Zxing开源代码(三)编码思路及代码分析脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

2021SC@SDUSC

目录

  • 一、demo引入
  • 二、编码关键类详解
    • 2.1 WrITer
    • 2.2 EncodeHintTyPE
    • 2.3 WriterException
    • 2.4 MultiFormatWriter
  • 三、生成二维码图片
    • 3.1 Java SE平台
    • 3.2 AndROId 平台
  • 小结
  • 参考资料


前言F1a;Zxing是一个开Java类库用于解析多种格式的条形码和二维码。本篇主要分析Zxing的二维码是如何进行编码生成的。博客分析了Zxing可以支持的多种二维码/条形码编码生成的一般步骤,即各种条码编码的共用关键类。在后续的代码分析中,我将分别对不同的二维码/条形码的编码算法进行分析。

一、demo引入

在上篇博客的demo中可以看出,二维码的生成,是从下面这个函数开始的:

BitMatrix encode = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);

BitMatrix的matrix对象包含了一个二维码的所有信息,用户得到它之后就可以绘制二维码了。

MultiFormatWriter是一个factory类,;multiFormatWriter.encode用来对不同的码格式的编码方法(write)进行寻找,实际生成二维码的工作是在各个不同码的Encoder.encoder方法中实现的。

二、编码关键类详解

2.1 Writer

Writer类是生成条形码图像的所有对象的基类, 在实现类可以生成二维码、条形码等其他图形编码。共有两个方法,都是用于生成二维码:

public interface Writer {

  BitMatrix encode(String contents, BarcodeFormat format, int width, int height)
      throws WriterException;

  BitMatrix encode(String contents,
                   BarcodeFormat format,
                   int width,
                   int height,
                   Map<EncodeHintType,?> hints)
      throws WriterException;
      
}

方法参数说明如下:

参数说明
String contents二维码/条形码中要编码的内容
BarcodeFormat format要生成的二维码/条形码格式
int width以像素为单位的首选
int height以像素为单位的首选高度
Map<EncodeHintType,?> hints提示向编码器提供其他参数

从上面可以看出,除了我们常规认为的编码需要内容之外,还有其他不少的信息,如编码的方式,编码的首选宽高度(首选的意思是:生成的图片的参考尺寸,如二维码是正方形,如果给一个矩形,则会留白;条形码为矩形,如果给一个正方形,则也会留白)。

2.2 EncodeHintType

由2.1中encode方法可以看出,编码包括参数Map<EncodeHintType, ?>,key为EncodeHintType枚举,此枚举是一组提示,您可以传递给编写者以指定其行为。枚举参数如下:

参数说明
ERROR_CORRECTION容错率,指定容错等级,例如二维码中使用的ErrorCorrectionLevel, Aztec使用Integer。分为四个等级:L/M/Q/H, 等级越高,容错率越高,识别速度降低。例如一个角被损坏,容错率高的也许能够识别出来。通常为H
CHARACTER_SET编码集,通常有中文,设置为 utf-8
DATA_MATRIX_Shape指定生成的数据矩阵的形状,类型为SymbolShapeHint
MIN_SIZE指定最小二维码/条形码大小
MAX_SIZE指定最大二维码/条形码大小
MargIN生成条码的时候使用,指定边距,单位像素,受格式的影响。类型Integer, 或String代表的数字类型。默认为4
PDF417_COMPACT指定是否使用PDF417紧凑模式,类型Boolean
PDF417_COMPACTION指定PDF417的紧凑类型
PDF417_DIMENSIONS指定PDF417的最大最小行列数
AZTEC_LAYERSaztec编码相关
QR_VERSION指定二维码版本,版本越高越复杂,反而不容易解析
QR_MASK_PATTERN指定要使用的二维码掩码图案。默认情况下,代码将自动选择最佳遮罩图案。
GS1_FORMAT指定是否应将数据编码为GS1标准
FORCE_CODE_SET强制使用哪种编码。目前仅用于Code-128代码集

2.3 WriterException

除上述外,我们还可以看到,在类Writer的两个生成方法中,都有异常处理throws WriterException。WriterException是一个基类,涵盖使用Writer框架编码条形码时可能出现的异常范围。

public final class WriterException extends Exception {

  public WriterException() {}

  public WriterException(String message) {
    super(message);
  }

  public WriterException(Throwable cause) {
    super(cause);
  }

}

2.4 MultiFormatWriter

MultiFormatWriter是一个工厂类,它为请求的编码格式查找适当的Writer子类,并使用提供的内容对二维码/条形码进行编码。由下面代码可以看出Zxing所支持的二维码、条形码的类型。这些类型在枚举类BarcodeFormat也可以看到。

public final class MultiFormatWriter implements Writer {

  @override
  public BitMatrix encode(String contents,
                          BarcodeFormat format,
                          int width,
                          int height) throws WriterException {
    return encode(contents, format, width, height, null);
  }

  @Override
  public BitMatrix encode(String contents,
                          BarcodeFormat format,
                          int width, int height,
                          Map<EncodeHintType,?> hints) throws WriterException {

    Writer writer;
    switch (format) {
      case EAN_8: writer = new EAN8Writer();break;
      case UPC_E:writer = new UPCEWriter();break;
      case EAN_13:writer = new EAn13Writer();break;
      case UPC_A:writer = new UPCAWriter();break;
      case QR_CODE:writer = new QRCodeWriter();break;
      case CODE_39:writer = new Code39Writer();break;
      case CODE_93:writer = new Code93Writer();break;
      case CODE_128:writer = new Code128Writer();break;
      case ITF:writer = new ITFWriter();break;
      case PDF_417:writer = new PDF417Writer();break;
      case CODABAR:writer = new CodaBarWriter();break;
      case DATA_MATRIX:writer = new DatamatrixWriter();break;
      case AZTEC:writer = new AztecWriter();break;
      default:
        throw new IllegalargumentException("No encoder available for format " + format);
    }
    return writer.encode(contents, format, width, height, hints);
  }

}

三、生成二维码图片

通过上述类及其方法,选择所需的编码方式进行编码后,得到的是一个BitMatrix, 如果需要显示出来则要根据不同平台来处理。

3.1 Java SE平台

1、将BitMatrix转换成BufferedImage。其方法为:

public static BufferedImage toBufferedImage(BitMatrix matrix, MatrixToImageconfig config)

其中,BitMatrix是二维码的描述对象;MatrixToImageConfig是二维码转换成BufferedImage的配置参数,其对象中只有两个域onColor和offcolor, 这样的配置表示生成的BufferedImage用两种颜色来表示二维码上的开关。

2、将BitMatrix转换成图片文件。其方法为:

public static boolean write(RenderedImage im, String formatName, File output) throws IOException

其中,RenderedImage im实现了RenderedImage接口,String formatName是图片文件格式,通常使用 png,File output是图片文件。

上面两步结合起来就直接将BitMatrix转换成图片文件。即:

public static void writeToPath(BitMatrix matrix, String format, Path file, MatrixToImageConfig config) throws IOException

3.2 Android 平台

类似的,在Android中也是先将BitMatrix转换成Bitmap, 然后再写入到文件中。

1、将BitMatrix转换成Bitmap。分为三步:

①创建一个一维int数组存放转换后的颜色值 ②根据BitMatrix中的位值设置相应像素点的颜色值 ③创建一个“相同”大小的Bitmap, 使用代表颜色的数组为其赋值(注意:颜色值中前两位默认为00, 表示透明)

2、Bitmap写入到文件中:

Bitmap.comPress(ComPRessFormat format, int quality, OutputStream stream)

具体细节不再介绍,在下面参考资料链接中都有。这并不是我分析代码的重点,因此不再赘述。

小结

本文分析了Zxing支持的各种二维码、条形码编码的公用方法,是接下来具体分析各种编码算法的前提,也是理解具体编码算法的基础。

参考资料

ZXing的应用 Zxing生成二维码思路和源码

脚本宝典总结

以上是脚本宝典为你收集整理的2021SC@SDUSC Zxing开源代码(三)编码思路及代码分析全部内容,希望文章能够帮你解决2021SC@SDUSC Zxing开源代码(三)编码思路及代码分析所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。