-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpage_writer.py
More file actions
190 lines (129 loc) · 3.43 KB
/
Copy pathpage_writer.py
File metadata and controls
190 lines (129 loc) · 3.43 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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import numpy as np
from PIL import Image, ImageDraw
from render_sentence import generate_strokes
# ==========================================
# PAGE SETTINGS
# ==========================================
PAGE_W = 2000
PAGE_H = 2800
LEFT_MARGIN = 180
RIGHT_MARGIN = 180
TOP_MARGIN = 180
LINE_BOX_HEIGHT = 120
RULE_GAP = 120
MAX_LINE_WIDTH = PAGE_W - LEFT_MARGIN - RIGHT_MARGIN
INK_COLOR = (20, 20, 20)
STROKE_WIDTH = 2
SHOW_RULES = True
# ==========================================
# HELPERS
# ==========================================
def get_bounds(strokes):
xs = []
ys = []
for stroke in strokes:
if len(stroke) == 0:
continue
xs.extend(stroke[:, 0])
ys.extend(stroke[:, 1])
if not xs:
return None
return (
min(xs),
max(xs),
min(ys),
max(ys)
)
# ==========================================
# RENDER PAGE
# ==========================================
def render_page(lines, output="page.png"):
img = Image.new(
"RGB",
(PAGE_W, PAGE_H),
"white"
)
draw = ImageDraw.Draw(img)
# ----------------------------------
# notebook rules
# ----------------------------------
if SHOW_RULES:
y = TOP_MARGIN
while y < PAGE_H - 100:
draw.line(
[(50, y), (PAGE_W - 50, y)],
fill=(220, 220, 220),
width=1
)
y += RULE_GAP
# ----------------------------------
# render lines
# ----------------------------------
baseline_y = TOP_MARGIN
for idx, line in enumerate(lines):
print(
f"[{idx+1}/{len(lines)}] {line}"
)
strokes = generate_strokes(
line,
temperature=0.10
)
bounds = get_bounds(strokes)
if bounds is None:
continue
min_x, max_x, min_y, max_y = bounds
width = max_x - min_x
height = max_y - min_y
if width <= 0:
continue
# ----------------------------------
# Fit inside notebook line box
# ----------------------------------
scale_x = MAX_LINE_WIDTH / width
scale_y = (
LINE_BOX_HEIGHT * 0.70
) / max(height, 1)
scale = min(
scale_x,
scale_y
)
# ----------------------------------
# Vertical centering
# ----------------------------------
center_y = (
min_y + max_y
) / 2
target_center = (
baseline_y
- LINE_BOX_HEIGHT * 0.30
)
for stroke in strokes:
pts = []
for x, y in stroke:
px = (
(x - min_x)
* scale
+ LEFT_MARGIN
)
py = (
-(y - center_y)
* scale
+ target_center
)
pts.append(
(
float(px),
float(py)
)
)
if len(pts) >= 2:
draw.line(
pts,
fill=INK_COLOR,
width=STROKE_WIDTH
)
baseline_y += RULE_GAP
if baseline_y > PAGE_H - 100:
break
img.save(output)
print(f"\nSaved: {output}")