用pyBarcode将数字放置在条形码下方

5 投票
1 回答
3301 浏览
提问于 2025-04-16 20:59

我正在使用 pyBarcode 来生成PNG格式的条形码,但条形码下面的数字在右边被截断了。我该怎么把它往左移动几像素呢?

数字被截断了

根据 文档,我需要做一些这样的事情:

barcode.writer.BaseWriter(paint_text=my_callback)

然后定义一个回调函数,像这样:

my_callback(xpos, ypos)

还有:

use self.text as text

我该如何将这些内容应用到我的Django视图中(如下所示)呢?

def barcode(request):
    import barcode
    from barcode.writer import ImageWriter
    from cStringIO import StringIO

    def mm2px(mm, dpi=300):
        return (mm * dpi) / 25.4

    class MyImageWriter(ImageWriter):
        def calculate_size(self, modules_per_line, number_of_lines, dpi=300):
            width = 2 * self.quiet_zone + modules_per_line * self.module_width
            height = 1.0 + self.module_height * number_of_lines
            if self.text:
                height += (self.font_size + self.text_distance) / 3

            return int(mm2px(width, dpi)), int(mm2px(height, dpi))

    f = BarcodeForm(request.GET)
    if f.is_valid():
        try:
            i = StringIO()
            bc_factory = barcode.get_barcode_class(f.PYBARCODE_TYPE[f.cleaned_data['barcode_type']])
            bc_factory.default_writer_options['quiet_zone'] = 1.0
            bc_factory.default_writer_options['text_distance'] = 1.0
            bc_factory.default_writer_options['module_height'] = 15.0
            bc_factory.default_writer_options['module_width'] = 0.3
            bc_factory.default_writer_options['font_size'] = 46

            bc = bc_factory(f.cleaned_data['text'], writer=MyImageWriter())
            bc.write(i)
            return HttpResponse(i.getvalue(), mimetype='image/png')
        except Exception, e:
            return HttpResponseBadRequest(str(e))
    else:
        return HttpResponseBadRequest('Missing text or unsupported barcode type: %s' % f.errors)

1 个回答

1

编辑:在回答后我注意到,你的工厂设置了 quiet_zone1.0。把它改回 6.5,我想这样看起来会好一些。

编辑2:我误解了你遇到的具体问题。

不管出于什么原因,pyBarcode 的作者把文本放在了条形码的中间。当渲染方法调用 _paint_text() 时,它传入了 xpos/2,这就把文本放在了条形码的中间。我想这在他使用的默认字体下是可以的,但当你增大字体时,就不再合适了。

相反,我通过重写 _paint_text() 方法,把文本放在了左边。在下面的最后一行,变量 pos 只是一个包含 (x,y) 坐标的元组,告诉 PIL 在条形码上绘制文本的位置。所以我确保 x 的位置和条形码对齐。如果你需要右对齐,可以调整 xpos 变量,找到合适的位置。

试试这个:

class MyImageWriter(ImageWriter):
    def calculate_size(self, modules_per_line, number_of_lines, dpi=300):
        width = 2 * self.quiet_zone + modules_per_line * self.module_width
        height = 1.0 + self.module_height * number_of_lines
        if self.text:
            height += (self.font_size + self.text_distance) / 3

        return int(mm2px(width, dpi)), int(mm2px(height, dpi))

    def _paint_text(self, xpos, ypos):
        # this should align your font to the left side of the bar code:
        xpos = self.quiet_zone
        pos = (mm2px(xpos, self.dpi), mm2px(ypos, self.dpi))
        font = ImageFont.truetype(FONT, self.font_size)
        self._draw.text(pos, self.text, font=font, fill=self.foreground)

撰写回答