2021SC@SDUSC


前言:本篇博客继续介绍PDF417二维码的编码步骤过程。


一、BarcodeMatrix

BarcodeMatrix类以易于访问的格式保存条形码的所有信息。
包括以下四个成员变量,分别表示二维码相应的矩阵、当前行、二维码的高和宽。

  private final BarcodeRow[] matrix;
  private int currentRow;
  private final int height;
  private final int width;

其构造函数为:
height和width分别为矩阵的高度(行)和宽度(列)。

  BarcodeMatrix(int height, int width) {
    matrix = new BarcodeRow[height];
    //将数组初始化为正确的宽度
    for (int i = 0, matrixLength = matrix.length; i < matrixLength; i++) {
      matrix[i] = new BarcodeRow((width + 4) * 17 + 1);
    }
    this.width = width * 17;
    this.height = height;
    this.currentRow = -1;
  }

二、BarcodeRow

BarcodeRow类用来创建条形码的行。

其成员变量有:

  private final byte[] row;
  private int currentLocation;

主要方法有:
其中,x表示在条中的位置;black为一个布尔值,如果条为黑色,则为真;如果条为白色,则为假;width表示条宽为多少个点。

set(int x, boolean black) 方法用来设置栏中的特定位置;addBar(boolean black, int width) 用来添加条。

  private void set(int x, boolean black) {
    row[x] = (byte) (black ? 1 : 0);
  }

  void addBar(boolean black, int width) {
    for (int ii = 0; ii < width; ii++) {
      set(currentLocation++, black);
    }
  }

getScaledRow(int scale)方法用于缩放行,scale 表示缩放图像的大小,必须大于或等于1;此函数返回缩放的行。

  byte[] getScaledRow(int scale) {
    byte[] output = new byte[row.length * scale];
    for (int i = 0; i < output.length; i++) {
      output[i] = row[i / scale];
    }
    return output;
  }

三、Compaction

Compaction类是一个枚举类,用来表示可能的PDF417条码压缩类型。
一共有四种类型: AUTO、TEXT、BYTE、NUMERIC

public enum Compaction {
  AUTO,
  TEXT,
  BYTE,
  NUMERIC
}

四、Dimensions

Dimensions是数据对象,用于指定PDF417条形码的最小行数和最大列数。

四个成员变量分别表示最小列数、最大列数、最小行数、最大行数。

public final class Dimensions {

  private final int minCols;
  private final int maxCols;
  private final int minRows;
  private final int maxRows;

  public Dimensions(int minCols, int maxCols, int minRows, int maxRows) {
    this.minCols = minCols;
    this.maxCols = maxCols;
    this.minRows = minRows;
    this.maxRows = maxRows;
  }
  public int getMinCols() {return minCols;}
  public int getMaxCols() {return maxCols;}
  public int getMinRows() {return minRows;}
  public int getMaxRows() {return maxRows;}
}

五、PDF417ErrorCorrection

PDF417ErrorCorrection类为PDF417的纠错码,遵循ISO/IEC 15438:2001(E)第4.10章所述算法。

getErrorCorrectionCodewordCount(int errorCorrectionLevel) 用来确定指定纠错级别的纠错码字数。
errorCorrectionLevel 为错误更正级别(0-8);
函数返回为纠错而生成的码字数。

  static int getErrorCorrectionCodewordCount(int errorCorrectionLevel) {
    if (errorCorrectionLevel < 0 || errorCorrectionLevel > 8) {
      throw new IllegalArgumentException("Error correction level must be between 0 and 8!");
    }
    return 1 << (errorCorrectionLevel + 1);
  }

getRecommendedMinimumErrorCorrectionLevel(int n)函数返回ISO/IEC 15438:2001(E)附录E中所述的建议最小错误纠正水平。
n 为数据码字的数量。

  static int getRecommendedMinimumErrorCorrectionLevel(int n) throws WriterException {
    if (n <= 0) {
      throw new IllegalArgumentException("n must be > 0");
    }
    if (n <= 40) {return 2;}
    if (n <= 160) {return 3;}
    if (n <= 320) {return 4;}
    if (n <= 863) {return 5;}
    throw new WriterException("No recommendation possible");
  }

generateErrorCorrection(CharSequence dataCodewords, int errorCorrectionLevel)函数根据ISO/IEC 15438:2001(E)中的4.10生成纠错码字。
dataCodewords 为数据码字数据码字;errorCorrectionLevel 为错误更正级别(0-8)。

  static String generateErrorCorrection(CharSequence dataCodewords, int errorCorrectionLevel) {
    int k = getErrorCorrectionCodewordCount(errorCorrectionLevel);
    char[] e = new char[k];
    int sld = dataCodewords.length();
    for (int i = 0; i < sld; i++) {
      int t1 = (dataCodewords.charAt(i) + e[e.length - 1]) % 929;
      int t2;
      int t3;
      for (int j = k - 1; j >= 1; j--) {
        t2 = (t1 * EC_COEFFICIENTS[errorCorrectionLevel][j]) % 929;
        t3 = 929 - t2;
        e[j] = (char) ((e[j - 1] + t3) % 929);
      }
      t2 = (t1 * EC_COEFFICIENTS[errorCorrectionLevel][0]) % 929;
      t3 = 929 - t2;
      e[0] = (char) (t3 % 929);
    }
    StringBuilder sb = new StringBuilder(k);
    for (int j = k - 1; j >= 0; j--) {
      if (e[j] != 0) {
        e[j] = (char) (929 - e[j]);
      }
      sb.append(e[j]);
    }
    return sb.toString();
  }

六、PDF417HighLevelEncoder

PDF417HighLevelEncoder类为PDF417的高级编码器。

含有多个成员变量。

成员变量取值说明
TEXT_COMPACTION0文本压缩代码
BYTE_COMPACTION1字节压缩代码
NUMERIC_COMPACTION2数字压缩代码
SUBMODE_ALPHA0文本压缩子模式Alpha
SUBMODE_LOWER1文本压缩子模式下
SUBMODE_MIXED2文本压缩子模式混合
SUBMODE_PUNCTUATION3文本压缩子模式标点符号
LATCH_TO_TEXT900模式锁存到文本压缩模式
LATCH_TO_BYTE_PADDED901模式锁存到字节压缩模式(字符数不是6的倍数)
LATCH_TO_NUMERIC902模式锁存到数字压缩模式
SHIFT_TO_BYTE913模式转换为字节压缩模式
LATCH_TO_BYTE924模式锁存到字节压缩模式(字符数为6的倍数)
ECI_USER_DEFINED925用户定义扩展信道解释(ECI)的标识符
ECI_GENERAL_PURPOSE926通用ECO格式的标识符
ECI_CHARSET927代码页字符集的ECI标识符
TEXT_MIXED_RAW文本压缩混合子模式的原始代码表
TEXT_PUNCTUATION_RAW文本压缩的原始代码表:标点子模式

成员函数为:

成员函数说明
encodeHighLevel(String msg, Compaction compaction, Charset encoding)使用ISO/IEC 15438:2001(E)附录P中描述的算法对PDF417消息执行高级编码。如果已选择字节压缩,则仅使用字节压缩。返回编码消息(字符值范围从0到928)
encodeText(CharSequence msg, int startpos,int count,StringBuilder sb, int initialSubmode)使用文本压缩对部分信息进行编码。返回此方法结束时的文本子模式
encodeBinary(byte[] bytes, int startpos,int count,int startmode,StringBuilder sb)使用字节压缩对部分信息进行编码。Unicode字符将使用cp437代码页转换为二进制。返回接收编码的码字。
determineConsecutiveDigitCount(CharSequence msg, int startpos)确定可使用数字压缩编码的连续字符数。返回请求的字符数。
determineConsecutiveTextCount(CharSequence msg, int startpos)确定可使用文本压缩编码的连续字符数。返回请求的字符数。
determineConsecutiveBinaryCount(String msg, int startpos, Charset encoding)确定可使用二进制压缩编码的连续字符数。返回请求的字符数。
Logo

鸿蒙生态一站式服务平台。

更多推荐