-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathImg2zpl.py
98 lines (70 loc) · 2.65 KB
/
Img2zpl.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
from PIL import Image
import re
class Img2zpl:
def __init__(self, zpl_version = 2):
self.zpl_version = zpl_version
def toZPL(self, image, with_cmd = False):
w,h = image.size
# Convert to RGB
temp = image
image = Image.new('RGB', (w, h), 'white')
image.paste(temp, mask=temp.split()[3])
# Convert to grayscale
image = image.convert('L')
# The width of the image must be multiple of 8
if w % 8 != 0:
raise Exception("Invalid width, not a multiple of 8: " + w)
# Size in bytes of the image
dataLength=f'{(w * h) / 8:01}'
# Size in bytes of an image's row
rowLength=f'{w / 8:01}'
lastRow = ''
out = ''
for y in range(h):
# Convert each image row to binary
currentLine = ''
for x in range(w):
grayscale = image.getpixel((x, y))
currentLine += ('0' if grayscale == 255 else '1')
currentBytes = []
for i in range(0, len(currentLine), 8):
currentBytes.append(currentLine[i:i+8])
# Add leading zeros to the last byte if < 8
n = currentBytes.pop()
currentBytes.append(f'{int(n):08}')
# Convert the row in hexadecimal
row = ''
for b in currentBytes:
row += format(int(b,2), '02x')
out += self.compressRow(row, lastRow)
lastRow = row
zpl = 'A,'
zpl += str(len(out.encode('utf-8'))) + ','
zpl += str(dataLength) + ','
zpl += str(rowLength) + ','
zpl += out
if with_cmd == False:
return zpl
else:
return '^GF' + zpl
def compressRow(self, current, last):
if current == last:
return ':'
outline = re.sub(r'0+$', ',', current)
outline = re.sub(r'F+$', '!', outline)
def callback(match):
original = match.group(0)
repeat = len(original)
count = ""
if repeat > 400:
count += "z" * (repeat // 400)
repeat %= 400
if repeat > 19:
count += chr(ord('f') + (repeat // 20))
repeat %= 20
if repeat > 0:
count += chr(ord('F') + repeat)
return count + original[1]
if self.zpl_version == 2:
return re.sub(r'(.)(\1{2,})', callback, outline)
return outline