-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprint.py
executable file
·68 lines (51 loc) · 1.8 KB
/
print.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
from render import *
from config import *
import time
def print_label(text, last=True):
image = render_label(text, border=False, for_print=True)
pbm = render_pbm(image)
bs = prepare_bitstream(pbm, (image.height, image.width), last=last)
log_line = f"Send to printer text={repr(text)} len={len(bs)}"
print(log_line)
with open("log.txt", "a+") as f:
f.write(log_line+"\n")
with open(PRINTER_DEV, "ab+") as f:
f.write(bs)
time.sleep(10) # estimated printing time
print("Done printing")
# Prepare the raw data stream to send to the printer
# last=False is for chain-printing and won't cut
# immediately after the print, but will still
# cut immediately before the next print
def prepare_bitstream(pbm, dims, last=True):
exp_header = f"P4\n{dims[1]} {dims[0]}\n".encode()
if pbm[0:len(exp_header)] != exp_header:
print("INVALID PBM HEADER")
print("EXPECTED", exp_header)
print("GOT", pbm[0:len(exp_header)])
pbm = pbm[len(exp_header):]
bs = b""
bs += b"\x00"*100 # Send zeros to clear state
bs += b"\x1B@" # Initialize
bs += b"\x1BiM\x40" # Auto cut
# Half cut mode
if last: bs += b"\x1BiK\x08"
else: bs += b"\x1BiK\x00"
bs += b"M\x02" # Compression
# Encode the image
width_bytes = dims[1] // 8
assert width_bytes in [8, 16]
for i in range(dims[0]):
offs = i*width_bytes
pad = (16 - width_bytes)//2
bs += b"G\x11\x00\x0F" # line start
bs += b"\x00"*pad # left padding
bs += bytes([_reverse_bits(x) for x in pbm[offs:offs+width_bytes][::-1]])
bs += b"\x00"*pad # right padding
bs += b"\x1A"
return bs
def _reverse_bits(x):
return int('{:08b}'.format(x)[::-1], 2)
# Test case
if __name__ == "__main__":
print_label("Hello")