/
binary_windows.py
195 lines (162 loc) · 6.33 KB
/
binary_windows.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
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
191
192
193
194
195
"""Module for generating Binary Windows resource."""
import os.path
from PIL import Image, ImageDraw, ImageFont
from utils.retrieve_query_parameter import retrieve_query_parameter
def resource_image(request, resource):
"""Create a image for Binary Windows resource.
Args:
request: HTTP request object (HttpRequest).
resource: Object of resource data (Resource).
Returns:
A list of Pillow image objects (list).
"""
BASE_IMAGE_PATH = "static/img/resources/binary-windows/"
FONT_PATH = "static/fonts/PatrickHand-Regular.ttf"
FONT = ImageFont.truetype(FONT_PATH, 300)
SMALL_FONT = ImageFont.truetype(FONT_PATH, 180)
# Retrieve parameters
parameter_options = valid_options()
number_of_bits = retrieve_query_parameter(request, "number_bits", parameter_options["number_bits"])
value_type = retrieve_query_parameter(request, "value_type", parameter_options["value_type"])
dot_counts = retrieve_query_parameter(request, "dot_counts", parameter_options["dot_counts"])
images = []
page_sets = [("binary-windows-1-to-8.png", 8)]
if number_of_bits == "8":
page_sets.append(("binary-windows-16-to-128.png", 128))
for (filename, dot_count_start) in page_sets:
image = Image.open(os.path.join(BASE_IMAGE_PATH, filename))
image = add_digit_values(image, value_type, True, 660, 724, 1700, FONT)
if dot_counts:
image = add_dot_counts(image, dot_count_start, SMALL_FONT)
image = image.rotate(90, expand=True)
images.append(image)
images.append(back_page(BASE_IMAGE_PATH, FONT, value_type))
return images
def back_page(BASE_IMAGE_PATH, FONT, value_type):
"""Return a Pillow object of back page of Binary Windows.
Args:
BASE_IMAGE_PATH: Base image path for finding images (str).
FONT: Pillow ImageFont for writing text (ImageFont).
value_type: Type of value representation used (str).
Returns:
Pillow Image of back page (Image).
"""
image = Image.open(os.path.join(BASE_IMAGE_PATH, "binary-windows-blank.png"))
image = add_digit_values(image, value_type, False, 660, 724, 650, FONT)
image = image.rotate(90, expand=True)
return image
def add_dot_counts(image, starting_value, font):
"""Add dot count text onto image.
Args:
image: The image to add text to (Pillow Image).
starting_value: Number on left window (int).
font: Font used for adding text (Pillow Font).
Returns:
Pillow Image with text added (Pillow Image).
"""
value = starting_value
draw = ImageDraw.Draw(image)
coord_x = 660
coord_x_increment = 724
coord_y = 1000
for i in range(4):
text = str(value)
text_width, text_height = draw.textsize(text, font=font)
text_coord_x = coord_x - (text_width / 2)
text_coord_y = coord_y - (text_height / 2)
draw.text(
(text_coord_x, text_coord_y),
text,
font=font,
fill="#000"
)
coord_x += coord_x_increment
value = int(value / 2)
return image
def add_digit_values(image, value_type, on, x_coord_start, x_coord_increment, base_y_coord, font):
"""Add binary values onto image.
Args:
image: The image to add binary values to (Pillow Image).
value_type: Either "binary" for 0's and 1's, or "lightbulb" for
lit and unlit lightbulbs (str).
on: True if binary value is on/lit, otherwise False (bool).
x_coord_start: X co-ordinate starting value (int).
x_coord_increment: X co-ordinate increment value (int).
base_y_coord: Y co-ordinate value (int).
font: Font used for adding text (Pillow Font).
Returns:
Pillow Image with binary values (Pillow Image).
"""
text_coord_x = x_coord_start
if value_type == "binary":
if on:
text = "1"
else:
text = "0"
elif value_type == "lightbulb":
if on:
image_file = "col_binary_lightbulb.png"
else:
image_file = "col_binary_lightbulb_off.png"
lightbulb = Image.open(os.path.join("static/img/topics/", image_file))
(width, height) = lightbulb.size
SCALE_FACTOR = 0.6
lightbulb = lightbulb.resize((int(width * SCALE_FACTOR), int(height * SCALE_FACTOR)))
(width, height) = lightbulb.size
lightbulb_width = int(width / 2)
lightbulb_height = int(height / 2)
if not on:
lightbulb = lightbulb.rotate(180)
for i in range(4):
draw = ImageDraw.Draw(image)
if value_type == "binary":
text_width, text_height = draw.textsize(text, font=font)
coord_x = text_coord_x - (text_width / 2)
coord_y = base_y_coord - (text_height / 2)
draw.text(
(coord_x, coord_y),
text,
font=font,
fill="#000"
)
elif value_type == "lightbulb":
coords = (text_coord_x - lightbulb_width, base_y_coord - lightbulb_height + 75)
image.paste(lightbulb, box=coords, mask=lightbulb)
text_coord_x += x_coord_increment
return image
def subtitle(request, resource):
"""Return the subtitle string of the resource.
Used after the resource name in the filename, and
also on the resource image.
Args:
request: HTTP request object (HttpRequest).
resource: Object of resource data (Resource).
Returns:
text for subtitle (str).
"""
number_of_bits = retrieve_query_parameter(request, "number_bits")
value_type = retrieve_query_parameter(request, "value_type")
dot_counts = retrieve_query_parameter(request, "dot_counts")
if dot_counts:
count_text = "with dot counts"
else:
count_text = "without dot counts"
TEMPLATE = "{num_bits} bits - {value} - {counts}"
text = TEMPLATE.format(
num_bits=number_of_bits,
value=value_type,
counts=count_text
)
return text
def valid_options():
"""Provide dictionary of all valid parameters.
This excludes the header text parameter.
Returns:
All valid options (dict).
"""
return {
"number_bits": ["4", "8"],
"value_type": ["binary", "lightbulb"],
"dot_counts": [True, False],
"paper_size": ["a4", "letter"],
}