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
|
from pathlib import Path
from PIL import ImageFont
from shapely.geometry import Polygon
import cv2
import os.path
import random
import subprocess
import json
from colorthief import ColorThief
import get_images
def draw_with_border(x, y, message, color_fill, color_border, font, draw):
border_width = max((font.size // 25), 2)
for i in range(1, border_width + 1):
draw.text((x, y + i), message, fill=color_border, font=font)
draw.text((x, y - i), message, fill=color_border, font=font)
draw.text((x + i, y), message, fill=color_border, font=font)
draw.text((x - i, y), message, fill=color_border, font=font)
draw.text((x - i, y - i), message, fill=color_border, font=font)
draw.text((x - i, y + i), message, fill=color_border, font=font)
draw.text((x + i, y - i), message, fill=color_border, font=font)
draw.text((x + i, y + i), message, fill=color_border, font=font)
draw.text((x, y), message, fill=color_fill, font=font)
def detect(filename):
result = subprocess.run(
[
"conda",
"activate",
"detection",
"&&",
"python",
"anime-face-detector/main.py ",
"-i",
filename,
"-o",
"output.json",
],
shell=True,
stdout=subprocess.DEVNULL,
)
with open("output.json", "r") as f:
output = json.load(f)
print(output)
return [f["bbox"] for f in output[filename]]
def set_font(image, message, font_name="fonts/Caveat-Bold.ttf"):
# keep increasing font size until the font area is 1/5th the size of image
font_size = 10
font = ImageFont.truetype(font_name, size=font_size)
image_area = image.size[0] * image.size[1]
font_area = font.getsize(message)[0] * font.getsize(message)[1]
while (image_area / 3) > font_area:
font_size = font_size + 5
font = ImageFont.truetype(font_name, size=font_size)
font_area = font.getsize(message)[0] * font.getsize(message)[1]
return font
def messages_multiline(text, font, image):
image_size = image.size
lines = []
if image_size[0] > image_size[1]:
# image_width is boxed width, if its too long, dont make text go all the way across
image_width = image_size[0] / random.uniform(1, 1.5)
else:
image_width = image_size[0]
if font.getsize(text)[0] <= image_width:
# if it can fit in one line, don't do anything
lines.append(text)
else:
words = text.split(" ")
i = 0
while i < len(words):
line = ""
while (
i < len(words) and font.getsize(line + words[i] + " ")[0] <= image_width
):
line = line + words[i] + " "
i += 1
if not line:
line = words[i]
i += 1
lines.append(line.rstrip())
return lines
def get_colors(file_name):
color_thief = ColorThief(file_name)
return color_thief.get_palette(color_count=2, quality=1)
def randomize_location(image, messages, font, faces):
image_size = image.size
x_coordinate = 0
y_coordinate = 0
for message in messages:
font_area = font.getsize(message)
# get widest line
if font_area[0] > x_coordinate:
x_coordinate = font_area[0]
# get total line height
y_coordinate = y_coordinate + font_area[1]
# try to find a location for text that doesn't overflow
# randomize locations that still fit
placed = False
tries = 0
while placed is False and tries < 20:
placed = True
x = random.randrange(0, image_size[0] - x_coordinate)
y = random.randrange(0, image_size[1] - y_coordinate)
for face in faces:
if is_intersected(face, (x, y, x + x_coordinate, y + y_coordinate)):
placed = False
tries = tries + 1
get_images.logging.info("tried: %i" % tries)
return (x, y, len(faces))
def is_intersected(face, text):
face_polygon = Polygon(
[(face[0], face[1]), (face[2], face[1]), (face[2], face[3]), (face[0], face[3])]
)
text_polygon = Polygon(
[(text[0], text[1]), (text[2], text[1]), (text[2], text[3]), (text[0], text[3])]
)
return face_polygon.intersects(text_polygon)
def get_quote(p):
with open(p, "r", encoding="utf-8") as f:
lines = f.read().splitlines()
return random.choice(lines)
|