-
Notifications
You must be signed in to change notification settings - Fork 0
/
generate_art.py
94 lines (76 loc) · 2.83 KB
/
generate_art.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
from PIL import Image, ImageDraw, ImageChops
import random
import colorsys
def random_color():
h = random.random()
s = 1
v = 1
float_rgb = colorsys.hsv_to_rgb(h, s, v)
rgb = [int(x * 255) for x in float_rgb]
return tuple(rgb)
def interpolate(start_color, end_color, factor: float):
recip = 1 - factor
return (
int(start_color[0] * recip + end_color[0] * factor),
int(start_color[1] * recip + end_color[1] * factor),
int(start_color[2] * recip + end_color[2] * factor)
)
def generate_art(path: str):
print('Generating Art !')
target_size_px = 512
scale_factor = 2
image_size_px = target_size_px * scale_factor
padding_px = 16 * scale_factor
image_bg_color = (0, 0, 0)
start_color = random_color()
end_color = random_color()
image = Image.new("RGB", size=(image_size_px, image_size_px), color=image_bg_color)
# Draw some lines
draw = ImageDraw.Draw(image)
points = []
# Generate the points
for _ in range(10):
random_point = (
random.randint(padding_px, image_size_px - padding_px),
random.randint(padding_px, image_size_px - padding_px)
)
points.append(random_point)
# Draw bounding box
min_x = min([p[0] for p in points])
max_x = max([p[0] for p in points])
min_y = min([p[1] for p in points])
max_y = max([p[1] for p in points])
# draw.rectangle((min_x, min_y, max_x, max_y), outline=(230, 230, 230))
# Center the image
delta_x = min_x - (image_size_px - max_x)
delta_y = min_y - (image_size_px - max_y)
for iterator, point in enumerate(points):
points[iterator] = (point[0] - delta_x // 2, point[1] - delta_y // 2)
min_x = min([p[0] for p in points])
max_x = max([p[0] for p in points])
min_y = min([p[1] for p in points])
max_y = max([p[1] for p in points])
# draw.rectangle((min_x, min_y, max_x, max_y), outline=(255, 0, 0))
# Draw the points
thickness = 0
n_points = len(points) - 1
for iterator, point in enumerate(points):
# overlay canvas
overlay_image = Image.new("RGB", size=(image_size_px, image_size_px), color=image_bg_color)
overlay_draw = ImageDraw.Draw(overlay_image)
p1 = point
if iterator == n_points:
p2 = points[0]
else:
p2 = points[iterator + 1]
line_xy = (p1, p2)
color_factor = iterator / n_points
line_color = interpolate(start_color, end_color, color_factor)
thickness += scale_factor
overlay_draw.line(line_xy, fill=line_color, width=thickness)
image = ImageChops.add(image, overlay_image)
image = image.resize((target_size_px, target_size_px), resample=Image.ANTIALIAS)
image.save(path)
if __name__ == "__main__":
for i in range(10):
generate_art(f"image_{i}.png")