zxing设置条码两边空白(EncodeHintType.MARGIN)无效的分析

2023-10-27

最新项目需要使用到zxing生成条码,条码格式为CODE128,CODE128的规则可参考:点击打开链接

当调用

MultiFormatWriter().encode(str,BarcodeFormat.CODE_128, mwidth, mHeight, hints)
       后生成的矩阵数据转换为Bitmap图时,会产生很大的左右两边的空白,zxing提供了 EncodeHintType.MARGIN选项来设置左右空白,很多时候无效,但偶然会成功,很困惑,所以追踪了一下代码,明白了其生成的原理,现以源码解析的方式整理如下。

此处,以类似“901001*C005”格式的内容来分析,编码格式为CODE128。

       1、

BitMatrix matrix = new MultiFormatWriter().encode(str,BarcodeFormat.CODE_128, mwidth, mHeight, hints);
此处没什么讲的生成条码/二维码的核心代码,zxing使用方法可以去百度/谷歌。

2、追踪encode函数,其原型MultiFormatWriter.java中,代码如下:

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 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_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);
  }
可以看到其采用工厂模式,将任务分发到了各个实现类中,以本测试CODE128格式为例,其使用的是Code128Writer中的encode函数,接着追踪到该单元中。

3、

public final class Code128Writer extends OneDimensionalCodeWriter {
@Override
  public BitMatrix encode(String contents,
                          BarcodeFormat format,
                          int width,
                          int height,
                          Map<EncodeHintType,?> hints) throws WriterException {
    if (format != BarcodeFormat.CODE_128) {
      throw new IllegalArgumentException("Can only encode CODE_128, but got " + format);
    }
    return super.encode(contents, format, width, height, hints);
  }
@Override
  public boolean[] encode(String contents) {
    int length = contents.length();
   /*
    *省略,就是根据CODE128的规则,生成一个一维的数组,每个元素代表有效内容的条码表示,true代表“条”,false,代表空,此处测试内容为901001*C005,生成的一维数组长度为134,
    */
   }
}
看到encode(String contents,BarcodeFormat......)调用了其父类的encode函数,继续追踪。

4、

@Override
  public BitMatrix encode(String contents,
                          BarcodeFormat format,
                          int width,
                          int height,
                          Map<EncodeHintType,?> hints) throws WriterException {
    if (contents.isEmpty()) {
      throw new IllegalArgumentException("Found empty contents");
    }

    if (width < 0 || height < 0) {
      throw new IllegalArgumentException("Negative size is not allowed. Input: "
                                             + width + 'x' + height);
    }

    int sidesMargin = getDefaultMargin();
    if (hints != null) {
      Integer sidesMarginInt = (Integer) hints.get(EncodeHintType.MARGIN);
      if (sidesMarginInt != null) {
        sidesMargin = sidesMarginInt;
      }
    }

    boolean[] code = encode(contents);
    return renderResult(code, width, height, sidesMargin);
  }
此处可以看到,我们设置的EncodeHintsType.MARGIN出现了,代码的具体含义就是,你要是设置了该值就取你设置的值,如果没有设置,去默认值(10),代码为:

 public int getDefaultMargin() {
    // CodaBar spec requires a side margin to be more than ten times wider than narrow space.
    // This seems like a decent idea for a default for all formats.
    return 10;
  }
然后其其调用了encode(String contents),该函数在OneDimensionalCodeWriter类中声明为抽象方法,下放到子类中实现,此处就是标题3处Code128Writer类中实现的encode(String content)生成一个一维数组。

接下来关键的内容来,函数renderResult。在该函数中计算了生成的矩阵的大小,其有你传入的宽、生成的一维数组长度、你设置的MARGIN三个参数共同决定,对于一维条码,高(需大于1)并无大用。

5、

 private static BitMatrix renderResult(boolean[] code, int width, int height, int sidesMargin) {
    int inputWidth = code.length;
    // Add quiet zone on both sides.
    int fullWidth = inputWidth + sidesMargin;
    int outputWidth = Math.max(width, fullWidth);
    int outputHeight = Math.max(1, height);

    int multiple = outputWidth / fullWidth;
    int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;

    BitMatrix output = new BitMatrix(outputWidth, outputHeight);
    for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
      if (code[inputX]) {
        output.setRegion(outputX, 0, multiple, outputHeight);
      }
    }
    return output;
  }
首先,inputWidth即根据CODE128规则生成的一维数组的长度;此处为134

接着,fullWidth即实际内容宽度和你设置的空白宽度;假设,我设置MARGIN为1,此处fullwidth为135;

接下来,是获取输出矩阵的宽和高,用了取较大值的数学函数max;假设我们设置的需要的条码宽和高分别为:300和100,此处outputWidth为300,outputHeigth为100;

接着,关键代码,计算实际内容缩放的比例:multiple,此处可得300/135=2,;

然后,可计算真实的左右空白:leftPadding,此处为:(300 - 135*2)/2 = 15;

然后,就是根据计算好的宽高及空白,生成矩阵。

我们可以在拿另一个例子解析下,宽设置为270,MARGIN设置为0,故multiple=2,leftPading = 0;然后生成的条码没有空白,但我们其他参数不变,宽设置为260,得multiple = 1;leftPading = (260 - 134*1)/2 = 62,两边有很大的空白。

       结束语,之所以,zxing会采用这种策略,就是为了保持条码中的比例,以免失真出现无法识别的条码矩阵。



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

zxing设置条码两边空白(EncodeHintType.MARGIN)无效的分析 的相关文章

随机推荐

  • More Effective C++条款10:在constructors内阻止资源泄露

    想像你正在开发一个多媒体通信薄软件 这个软件可以放置包括人名 地址 电话号码等文字 以及一张个人相片和一段个人声音 为了简单起见 本文中假设只包含个人相片和声音 代码实现下 include
  • 【华为OD统一考试A卷

    华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一修改为OD统一考试 A卷 和OD统一考试 B卷 你收到的链接上面会标注A卷还是B卷 请注意 根据反馈 目前大部分收到的都是
  • 安川机器人外部信号怎么接线_工业机器人十万个怎么办-不清楚机器人IO信号怎么办?...

    I O信号介绍 I O信号就是输入 IN 输出 OUT 信号 比如传送带上货物运动到某一位置 传感器检测到后发出一个信号1给机器人和传送带 传送带接收到信号后会停止 机器人接到信号就会取走货物放到指定位置 机器人在一个码盘上码好货物后 发送
  • 这是一篇很好的很详细的http具体内容解释!和MIME解释

    转载 https www cnblogs com Dev0ps p 8074972 html HTTP请求由三部分组成 分别是 请求行 消息报头 请求正文 请求行 格式 Method Request URI HTTP Version CRL
  • 【数据挖掘复习题】

    文章目录 一 单选题 共78题 二 多选题 共31题 三 判断题 共54题 一 单选题 共78题 1 2 3 4 5 6 7 8 9 10 D C A D A B D C A D 11 12 13 14 15 16 17 18 19 20
  • 如何判断数组和对象

    一 当调用 Object prototype toString call someObject 时 实际上会调用 Object prototype toString 方法 并将 this 设置为 someObject 然后返回一个字符串 表
  • 学会Python有哪些可以做的兼职?所有途径全在这里了...

    可以干的兼职有好多 主要围绕Python的应用方向来 自媒体 现在很多搞技术的都开始进入自媒体领域 比如微信公众号 知乎 B站 抖音 小红书等 这些平台上只要你有流量 你就可以通过广告 播放量 带货等方式赚钱 当然了 自媒体需要积累 如果能
  • 数模学习(模糊数学篇)——模糊识别(python实现)

    目录 一 储备知识 1 课本定义 2 通俗理解 引入小例 如何识别 二 模糊识别方法 1 最大隶属度原则 计算方法 使用方向 2 择近原则 择近度计算方法和使用方向 三 模糊识别例题 例题1 湖泊水质识别 1 指标库标准化和样品库标准化 2
  • python爬虫怎么学?浅谈python爬虫学习的10大步骤

    如今 做跨境电商与海外社媒的从业者可谓是越来越多了 若想采集海外的相关数据 基本上是离不开爬虫的 很多小白都是不太了解这一块内容的 并且网络爬虫基本上是要使用python语言的 所以这里我就来讲讲用python爬虫要怎么学 以及分为几个步骤
  • 4.mybatis 高级结果查询

    商品订单模型 一个用户可以下n个订单 一个订单只能属于一个用户 一个订单可以有多个订单详情 订单和订单详情是一对多的关系 一个订单中可以有多个商品 一个商品也可以属于多个订单 订单和商品多对多的关系 关联查询几个需要注意的细节 1 超过三个
  • 计算机管理中的用户和组里的名称和全名有什么不同

    用户名是登录使用的 全名就是一个注释 组决定了用户的权限 计算机上 System 组的权限最高 用户中 Administrators 组的权限最高 Users 组居中 Guests 组最低 根据权限的逐渐降低 用户可访问的文件 可更改的设置
  • JAVA项目:后台管理页面——显示数据库中所有信息+删除和编辑(MySQL)

    此DEMO包含以下功能 后台管理界面 删除 修改 显示数据库里所有数据 修改编辑界面 表格检验 修改数据库里的值 后台管理界面 头像为默认头像 视频暂未上传 backstageUI jsp
  • get传递数组参数

    get请求时传递的参数有一个是数组时 要做序列化处理 下面是不需要用插件就可以解决的方法 axios有一个方法 paramsSerializer 可以处理params的数组 下面举例 vue文件里请求时传的是三个参数 methods 发送请
  • MotionBuilder调整骨骼大小尺寸

    需要先选中骨骼太能调整尺寸大小
  • 交通事故致因分析

    1 挖掘背景 随着时代的发展 我们的出行变的越来越便利的同时 也带来的越发严重的交通安全事故 我国的经济高速发展 全国汽车保有量 交通道路 人口等都在不断的增加 同时道路交通安全事故也进入高发期 分析事故发生的原因 找到事故发生的内在规律
  • 幂等的这几个问题没有考虑到,你恐怕是在写Bug吧!

    免费视频福利推荐 2T免费学习视频 内含精选高频面试题 SSM Spring全家桶 微服务 MySQL MyCat 集群 分布式 高并发 中间件 Linux 网络 多线程 Jenkins Nexus Docker ELK等等免费学习视频 持
  • Python 操作MySql数据库(封装、优雅)

    Python 记录操作MySql数据库 封装 优雅 前言 封装代码 进行测试 结果展示 前言 学了pymysql第三方库 pip install pymysql 来操作MySql数据库后 浅记一下对MySql进行 关于我的MySql之优雅封
  • ValueError: shape mismatch: objects cannot be broadcast to a single shape 画条形图bar报错

    ValueError shape mismatch objects cannot be broadcast to a single shape plt bar x y 可能是条形图的x和y的数组长度不同造成的 需要修改数据 保持一致
  • 前端手机号码校验

    vue前端手机号码校验
  • zxing设置条码两边空白(EncodeHintType.MARGIN)无效的分析

    最新项目需要使用到zxing生成条码 条码格式为CODE128 CODE128的规则可参考 点击打开链接 当调用 MultiFormatWriter encode str BarcodeFormat CODE 128 mwidth mHei