def write_image_surface(doc, printer, resolution=96): dppx = resolution / 96 # This duplicates the hinting logic in Page.paint. There is a # dependency cycle otherwise: # this → hinting logic → context → surface → this # But since we do no transform here, cairo_context.user_to_device and # friends are identity functions. widths = [int(math.ceil(p.width * dppx)) for p in doc.pages] heights = [ int(math.ceil(p._page_box.children[0].height * dppx)) for p in doc.pages ] max_width = max(widths) printer._raw(escpos.constants.ESC + b"3\x16") for page, width, height in zip(doc.pages, widths, heights): surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, max_width, height) context = cairo.Context(surface) pos_x = (max_width - width) / 2 page.paint(context, pos_x, 0, scale=dppx, clip=True) target = io.BytesIO() surface.write_to_png(target) target.seek(0) im = Image.open(target) im.load() im = convert_image(im) print_image(im, printer) printer._raw(escpos.constants.ESC + b"2")
def on_message(client, userdata: Context, msg: mqtt.MQTTMessage): try: payload = json.loads(msg.payload) except json.decoder.JSONDecodeError as e: print(f"JSON decode error {e}", flush=True) return subject = payload.get("subject") if subject is None: subject = "None" message = payload.get("message") if message is None: return attachments = payload.get("attachments") if attachments is None: attachments = {} sender = payload.get("from") formatted_time = time.strftime("%Y-%m-%dT%H:%M:%S") printer = userdata.printer print(f"New email from {sender}, subject: {subject}", flush=True) print(message, flush=True) # Print header parse_html( printer, TEMPLATE.render(subject=subject, time=formatted_time, sender=sender), {}) # Print message parse_html(printer, message, attachments) printer._raw(b"\n" * 3) print("Done!", flush=True)
def print_image(im: Image.Image, printer: escpos.escpos.Escpos): outp = [] header = escpos.constants.ESC + b"*\x21" + struct.pack("<H", im.width) im = im.transpose(Image.ROTATE_270).transpose(Image.FLIP_LEFT_RIGHT) line_height = 24 width_pixels, height_pixels = im.size top = 0 left = 0 while left < width_pixels: box = (left, top, left + line_height, top + height_pixels) im_slice = im.transform((line_height, height_pixels), Image.EXTENT, box) im_bytes = im_slice.tobytes() outp.append(header + im_bytes + b"\n") left += line_height printer._raw(b''.join(outp))
def print_codepage(printer, codepage): printer.charcode(codepage) # Table header printer.set(text_type='B') printer._raw(" %s\n" % " ".join(map(lambda s: hex(s)[2:], range(0, 16)))) printer.set() # The table for x in range(0, 16): # First column printer.set(text_type='B') printer._raw("%s " % hex(x)[2:]) printer.set() for y in range(0, 16): byte = six.int2byte(x * 16 + y) if byte in (ESC, CTL_LF, CTL_FF, CTL_CR, CTL_HT, CTL_VT): byte = ' ' printer._raw(byte) printer._raw(" ") printer._raw('\n')
def print_codepage(printer, codepage): if codepage.isdigit(): codepage = int(codepage) printer._raw(CODEPAGE_CHANGE + six.int2byte(codepage)) printer._raw("after") else: printer.charcode(codepage) sep = "" # Table header printer.set(text_type='B') printer._raw(" {}\n".format( sep.join(map(lambda s: hex(s)[2:], range(0, 16))))) printer.set() # The table for x in range(0, 16): # First column printer.set(text_type='B') printer._raw("{} ".format(hex(x)[2:])) printer.set() for y in range(0, 16): byte = six.int2byte(x * 16 + y) if byte in (ESC, CTL_LF, CTL_FF, CTL_CR, CTL_HT, CTL_VT): byte = ' ' printer._raw(byte) printer._raw(sep) printer._raw('\n')
def print_codepage(printer, codepage): if codepage.isdigit(): codepage = int(codepage) printer._raw(CODEPAGE_CHANGE + six.int2byte(codepage)) printer._raw("after") else: printer.charcode(codepage) sep = "" # Table header printer.set(text_type='B') printer._raw(" {}\n".format(sep.join(map(lambda s: hex(s)[2:], range(0, 16))))) printer.set() # The table for x in range(0, 16): # First column printer.set(text_type='B') printer._raw("{} ".format(hex(x)[2:])) printer.set() for y in range(0, 16): byte = six.int2byte(x * 16 + y) if byte in (ESC, CTL_LF, CTL_FF, CTL_CR, CTL_HT, CTL_VT): byte = ' ' printer._raw(byte) printer._raw(sep) printer._raw('\n')
# Print header parse_html( printer, TEMPLATE.render(subject=subject, time=formatted_time, sender=sender), {}) # Print message parse_html(printer, message, attachments) printer._raw(b"\n" * 3) print("Done!", flush=True) if __name__ == "__main__": printer = escpos.printer.Usb(0x0416, 0x5011) #printer = escpos.printer.Dummy() printer._raw(escpos.constants.ESC + b"@") context = Context(printer) client = mqtt.Client(userdata=context) client.on_connect = on_connect client.message_callback_add("printer/print", on_message) client.connect(os.getenv("MQTT_SERVER", "172.30.2.10"), 1883, 60) while True: try: client.loop() except (KeyboardInterrupt, SystemExit): print("Bye!") break