绘图条形码在绘图窗口中的显示与在保存的.pdf中不同

时间:2018-10-24 11:39:03

标签: python python-3.x matplotlib barcode code128

我在正确保存pdf时遇到了一些麻烦。我正在尝试绘制条形码标签,然后将其另存为pdf,如以下代码所示。我已经在Windows上安装了code128.ttf字体。另外,正如this帖子所述,我尝试将.savefig dpi参数设置为fig.dpi。

import os

import matplotlib.pyplot as plt

from matplotlib import font_manager as fm


def draw_label(label, label_dimensions_x=3.8189, label_dimensions_y=1.41732):

    # import barcode code128 font
    fpath = os.path.join("path", "to", "font", "code128.ttf")

    prop = fm.FontProperties(fname=fpath, size=58)

    fig, ax = plt.subplots(1, figsize=(label_dimensions_x,
                                       label_dimensions_y))

    plt.axis('off')
    plt.xticks([], [])
    plt.yticks([], [])
    plt.tight_layout()
    plt.xlim(0, label_dimensions_x)
    plt.ylim(0, label_dimensions_y)

    # plot barcode
    plt.text(label_dimensions_x / 2, label_dimensions_y / 2, label,
             ha='center', va='bottom',
             fontproperties=prop)

    plt.show()

    try:
        plt.savefig(os.path.join("path", "to", "output", label + '.pdf'),
                    dpi=plt.gcf().dpi)
    except PermissionError:
        logging.warning("Close the current label pdf's before running this script.")

    plt.close()

    return

draw_label('123456789')

This是在绘图窗口中输出的内容。

This是在.pdf保存文件中输出的结果,这种情况在所有标签上都会发生-好像数字1到9除了8不能打印一样。 编辑:如果我将普通文本字体(在本例中为Frutiger Roman)替换为code128.ttf,并将plt.axis('on')设置为不剪切,请参见this。承认,它不是很漂亮并且不太适合,但是它应该仍然可读。

2 个答案:

答案 0 :(得分:1)

山姆

首先,条形码不会照原样扫描。该字符串要求为Code128B添加开始字符,校验和和结束字符。所以,就是这样。

enter image description here

我建议更改为Code 39字体(不需要校验和,并且起始字符和终止字符相同:“ *”)或编写代码以产生校验和,并在{ {3}}。

第二,我怀疑在转换为PDF的过程中图形的边框存在问题。被转换的条形码的一小部分看起来更像字符串中的数字九。我怀疑正在进行一些图像剪辑。 Code 128 Wiki

请尝试替换常规文本字体,以确保条形码图像在转换中不会丢失。

已编辑答案,其中包括使用PNG代替PDF的建议。

如果您输出为PNG格式,我设法使该软件能够运行。我知道,现在的问题变成了如何将PNG转换为PDF。您可以先研究这里提到的一些库:enter image description here

简而言之,我建议您创建图形文件,然后将其嵌入文档文件中。

我还添加了用开始,校验和和终止字符构建条形码所需的代码:

import os

import matplotlib.pyplot as plt

from matplotlib import font_manager as fm

def draw_label(label, label_dimensions_x=3.8189, label_dimensions_y=1.41732):

    # import barcode code128 font
    fpath = os.path.join("./", "code128.ttf")

    prop = fm.FontProperties(fname=fpath, size=32)

    fig, ax = plt.subplots(1, figsize=(label_dimensions_x,
                                       label_dimensions_y))

    plt.axis('off')
    plt.xticks([], [])
    plt.yticks([], [])
    plt.tight_layout()
    plt.xlim(0, label_dimensions_x)
    plt.ylim(0, label_dimensions_y)

    # calc checksum THEN plot barcode
    weight = 1
    chksum = 104
    for x in label:
        chksum = chksum + weight*(ord(x)-32)
        weight = weight + 1
    chksum = chksum % 103
    chkchar = chr(chksum+32)
    label128 = "%s%s%s%s" % ('Ñ', label, chkchar, 'Ó')
    plt.text(label_dimensions_x / 2, label_dimensions_y / 2, label128,
             ha='center', va='bottom',
             fontproperties=prop)
    try:
        plt.savefig(os.path.join("./", label + '.png'))
    except PermissionError:
        logging.warning("Close the current label pdf's before running this script.")

    return

draw_label('123456789')
draw_label('987654321')
draw_label('Test&Show')

答案 1 :(得分:0)

使用matplotlib和字体会使事情变得过于复杂。直接生成图像并将其保存为PDF文件并不复杂,而且可靠得多。

正如Brian Anderson所指出的那样,仅对字符串中的字符进行编码是不够的。您需要添加一个开始码,一个校验和和一个停止码以制作完整的条形码。下面的功能'2014-11-01'会执行此操作,而将转换为图像作为一个单独的步骤。

code128_codes