From 175b67d4a5b6f19a14e7649b83145d4a2dce7699 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Sat, 7 Jun 2025 14:59:30 +0200 Subject: [PATCH] WIP --- src/libdib/label_printer.py | 167 +++++++++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 1 deletion(-) diff --git a/src/libdib/label_printer.py b/src/libdib/label_printer.py index 37765e5..918c8f2 100644 --- a/src/libdib/label_printer.py +++ b/src/libdib/label_printer.py @@ -1 +1,166 @@ -# TODO: make library calls for label maker +import datetime +import os + +import barcode +from barcode.writer import ImageWriter, mm2px + +from brother_ql.brother_ql_create import create_label +from brother_ql.raster import BrotherQLRaster +from brother_ql.backends import backend_factory +from brother_ql.labels import ALL_LABELS + +from PIL import Image, ImageDraw, ImageFont + + + +def px2mm(px, dpi=300): + return (25.4 * px) / dpi + + +class BrotherLabelWriter(ImageWriter): + def __init__(self, typ="62", max_height=350, rot=False, text=None): + super(BrotherLabelWriter, self).__init__() + label = next([l for l in ALL_LABELS if l.identifier == typ]) + assert label is not None + self.rot = rot + if self.rot: + self._h, self._w = label.dots_printable + if self._w == 0 or self._w > max_height: + self._w = min(max_height, self._h / 2) + else: + self._w, self._h = label.dots_printable + if self._h == 0 or self._h > max_height: + self._h = min(max_height, self._w / 2) + self._xo = 0.0 + self._yo = 0.0 + self._title = text + + def _init(self, code): + self.text = None + super(BrotherLabelWriter, self)._init(code) + + def calculate_size(self, modules_per_line, number_of_lines, dpi=300): + x, y = super(BrotherLabelWriter, self).calculate_size( + modules_per_line, number_of_lines, dpi + ) + + self._xo = (px2mm(self._w) - px2mm(x)) / 2 + self._yo = px2mm(self._h) - px2mm(y) + assert self._xo >= 0 + assert self._yo >= 0 + + return int(self._w), int(self._h) + + def _paint_module(self, xpos, ypos, width, color): + super(BrotherLabelWriter, self)._paint_module( + xpos + self._xo, ypos + self._yo, width, color + ) + + def _paint_text(self, xpos, ypos): + super(BrotherLabelWriter, self)._paint_text(xpos + self._xo, ypos + self._yo) + + def _finish(self): + if self._title: + width = self._w + 1 + height = 0 + max_h = self._h - mm2px(self._yo, self.dpi) + fs = int(max_h / 1.2) + font_path = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "Stranger back in the Night.ttf", + ) + font = ImageFont.truetype(font_path, 10) + while width > self._w or height > max_h: + font = ImageFont.truetype(font_path, fs) + width, height = font.getsize(self._title) + fs -= 1 + pos = ((self._w - width) // 2, 0 - (height // 8)) + self._draw.text(pos, self._title, font=font, fill=self.foreground) + return self._image + + +def print_name_label( + text, + margin=10, + rotate=False, + label_type="62", + printer_type="QL-700", +): + label = next([l for l in ALL_LABELS if l.identifier == label_type]) + if not rotate: + width, height = label.dots_printable + else: + height, width = label.dots_printable + + font_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "ChopinScript.ttf") + fs = 2000 + tw, th = width, height + if width == 0: + while th + 2 * margin > height: + font = ImageFont.truetype(font_path, fs) + tw, th = font.getsize(text) + fs -= 1 + width = tw + 2 * margin + elif height == 0: + while tw + 2 * margin > width: + font = ImageFont.truetype(font_path, fs) + tw, th = font.getsize(text) + fs -= 1 + height = th + 2 * margin + else: + while tw + 2 * margin > width or th + 2 * margin > height: + font = ImageFont.truetype(font_path, fs) + tw, th = font.getsize(text) + fs -= 1 + + xp = (width // 2) - (tw // 2) + yp = (height // 2) - (th // 2) + + im = Image.new("RGB", (width, height), (255, 255, 255)) + dr = ImageDraw.Draw(im) + + dr.text((xp, yp), text, fill=(0, 0, 0), font=font) + now = datetime.datetime.now() + date = now.strftime("%Y-%m-%d") + dr.text((0, 0), date, fill=(0, 0, 0)) + + base_path = os.path.dirname(os.path.realpath(__file__)) + fn = os.path.join(base_path, "bar_codes", text + ".png") + + im.save(fn, "PNG") + print_image(fn, printer_type, label_type) + + +def print_bar_code( + barcode_value, + barcode_text, + barcode_type="ean13", + rotate=False, + printer_type="QL-700", + label_type="62", +): + bar_coder = barcode.get_barcode_class(barcode_type) + wr = BrotherLabelWriter(typ=label_type, rot=rotate, text=barcode_text, max_height=1000) + + test = bar_coder(barcode_value, writer=wr) + base_path = os.path.dirname(os.path.realpath(__file__)) + fn = test.save(os.path.join(base_path, "bar_codes", barcode_value)) + print_image(fn, printer_type, label_type) + + +def print_image(fn, printer_type="QL-700", label_type="62"): + qlr = BrotherQLRaster(printer_type) + qlr.exception_on_warning = True + create_label(qlr, fn, label_type, threshold=70, cut=True) + + be = backend_factory("pyusb") + list_available_devices = be["list_available_devices"] + BrotherQLBackend = be["backend_class"] + + ad = list_available_devices() + assert ad + string_descr = ad[0]["string_descr"] + + printer = BrotherQLBackend(string_descr) + + printer.write(qlr.data)