aboutsummaryrefslogtreecommitdiffstats
path: root/utils.py
blob: bdb9eb224339f24001c346bd7f65a22493a83553 (plain)
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)