【问题标题】:Python Code128 encoder for Code128 barcode font用于 Code128 条形码字体的 Python Code128 编码器
【发布时间】:2019-03-13 15:01:24
【问题描述】:

正如标题所说,我有一个 Code128 字体,我想用它来打印条形码。但是,字符串需要在 Code128 中编码才能使条形码字体工作。我的应用使用 Python3 语言。

曾经在网上某处有一个示例如何将字符串编码为 Code128 字体,但我再也找不到了。

我确实想要一个字符串到 .svg 转换器。我特别想将字符串转换为 Code128 编码的字符串。

任何参考资料、Python3 中的代码 sn-ps 或文档将不胜感激。

编辑:我使用来自here 的字体。

【问题讨论】:

标签: python python-3.x barcode code128


【解决方案1】:

这是一个公认的答案,所以我将原始代码留在下面。但我更喜欢这种改进。

def list_join(seq):
    ''' Join a sequence of lists into a single list, much like str.join
        will join a sequence of strings into a single string.
    '''
    return [x for sub in seq for x in sub]

code128B_mapping = dict((chr(c), [98, c+64] if c < 32 else [c-32]) for c in range(128))
code128C_mapping = dict([(u'%02d' % i, [i]) for i in range(100)] + [(u'%d' % i, [100, 16+i]) for i in range(10)])
code128_chars = u''.join(chr(c) for c in [212] + list(range(33,126+1)) + list(range(200,211+1)))

def encode128(s):
    ''' Code 128 conversion for a font as described at
        https://en.wikipedia.org/wiki/Code_128 and downloaded
        from http://www.barcodelink.net/barcode-font.php
        Only encodes ASCII characters, does not take advantage of
        FNC4 for bytes with the upper bit set. Control characters
        are not optimized and expand to 2 characters each.
        Coded for https://stackoverflow.com/q/52710760/5987
    '''
    if s.isdigit() and len(s) >= 2:
        # use Code 128C, pairs of digits
        codes = [105] + list_join(code128C_mapping[s[i:i+2]] for i in range(0, len(s), 2))
    else:
        # use Code 128B and shift for Code 128A
        codes = [104] + list_join(code128B_mapping[c] for c in s)
    check_digit = (codes[0] + sum(i * x for i,x in enumerate(codes))) % 103
    codes.append(check_digit)
    codes.append(106) # stop code
    return u''.join(code128_chars[x] for x in codes)

def encode128(s):
    ''' Code 128 conversion for a font as described at
        https://en.wikipedia.org/wiki/Code_128 and downloaded
        from http://www.barcodelink.net/barcode-font.php
        Only encodes ASCII characters, does not take advantage of
        FNC4 for bytes with the upper bit set.
        It does not attempt to optimize the length of the string,
        Code B is the default to prefer lower case over control characters.
        Coded for https://stackoverflow.com/q/52710760/5987
    '''
    s = s.encode('ascii').decode('ascii')
    if s.isdigit() and len(s) % 2 == 0:
        # use Code 128C, pairs of digits
        codes = [105]
        for i in range(0, len(s), 2):
            codes.append(int(s[i:i+2], 10))
    else:
        # use Code 128B and shift for Code 128A
        mapping = dict((chr(c), [98, c + 64] if c < 32 else [c - 32]) for c in range(128))
        codes = [104]
        for c in s:
            codes.extend(mapping[c])
    check_digit = (codes[0] + sum(i * x for i,x in enumerate(codes))) % 103
    codes.append(check_digit)
    codes.append(106) # stop code
    chars = (b'\xd4' + bytes(range(33,126+1)) + bytes(range(200,211+1))).decode('latin-1')
    return ''.join(chars[x] for x in codes)

【讨论】:

  • 这非常有用。字体显然可以使用不同的字符来编码 START 和 STOP 字符。希望有您使用的字体的文档。
  • @TimRichardson 正如我在问题的 cmets 中所说,将代码映射到字体字符没有标准。这意味着要使字体可用,必须有定义映射的文档。我唯一的希望是代码不会太晦涩,无法根据需要调整映射。
猜你喜欢
  • 1970-01-01
  • 2015-04-29
  • 2012-08-06
  • 1970-01-01
  • 2020-06-06
  • 2017-06-19
  • 2012-11-08
  • 1970-01-01
  • 2017-05-23
相关资源
最近更新 更多