用pyBarcode将数字放置在条形码下方
我正在使用 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_zone
为 1.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)