aboutsummaryrefslogtreecommitdiffstats
path: root/utils.py
blob: 55a06231c4cd0e0ad5d446d2c088cc69f7987faa (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
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

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):
    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
    faces = detect(image.filename)
    print("faces found:",len(faces))
    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
    print("tried:",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)