This repository was archived by the owner on Aug 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathprinter.py
More file actions
131 lines (100 loc) · 2.53 KB
/
printer.py
File metadata and controls
131 lines (100 loc) · 2.53 KB
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import argparse
import os
import pathlib
from dataclasses import dataclass
from PIL import Image, ImageDraw
IMAGE_SIZE = 2400
POD_OUTER_DIA = 2.26
POD_INNER_DIA = 2.02
DPI = IMAGE_SIZE / POD_OUTER_DIA
CODON_HEIGHT = int(DPI * (POD_OUTER_DIA - POD_INNER_DIA) * 0.6)
CODON_WIDTH_TOLERANCE = 0.5
class _PrinterArgs(argparse.Namespace):
code: str = ""
output: pathlib.Path = None
pass
@dataclass
class _Codon(object):
color: str
startAngle: int
endAngle: int
pass
def _getArgs() -> _PrinterArgs:
parser = argparse.ArgumentParser(description="Create a printable barcode.")
parser.add_argument(
"code",
help="A 140 character code to make a barcode with."
)
parser.add_argument(
"-o", "--output",
type=pathlib.Path,
help="The path of the output image. By default it outputs to 'output/customBarcode.png'" # noqa
)
args = parser.parse_args(namespace=_PrinterArgs())
# verify the input code
if len(args.code) != 140:
print("The code is not 140 character!")
parser.exit()
pass
if any(c not in "10" for c in args.code):
print("The code has invalid characters! It can only have 1s and 0s.")
parser.exit()
pass
return args
def main():
args = _getArgs()
# Create the output directory if necessary
outputPath = args.output
if outputPath is None:
outputPath = pathlib.Path("output/customBarcode.png")
os.makedirs(outputPath.parent, exist_ok=True)
pass
else:
os.makedirs(outputPath.parent, exist_ok=True)
pass
# generate a list of codons
inputData = args.code
angleSize = 360 / len(inputData)
code: list[_Codon] = []
currentAngle = 0
i = 0
while i < len(inputData):
value = inputData[i]
# check for how many of the same color are in a row
changeValue = "0" if value == "1" else "1"
changeIndex = inputData.find(changeValue, i)
if changeIndex == -1:
changeIndex = i + 1
codonWidth = changeIndex - i
startAngle = currentAngle + CODON_WIDTH_TOLERANCE
endAngle = startAngle + (codonWidth * angleSize) - CODON_WIDTH_TOLERANCE
code.append(
_Codon(
"white" if value == "0" else "black",
startAngle,
endAngle
)
)
currentAngle += codonWidth * angleSize
i += codonWidth
pass
# create the image
with Image.new("1", (IMAGE_SIZE, IMAGE_SIZE), color=1) as im:
draw = ImageDraw.Draw(im)
for codon in code:
if codon.color == "white":
continue
draw.arc(
((0, 0), (IMAGE_SIZE, IMAGE_SIZE)),
codon.startAngle,
codon.endAngle,
fill=codon.color,
width=CODON_HEIGHT
)
pass
im.save(outputPath)
pass
pass
if __name__ == "__main__":
main()
pass