File size: 2,192 Bytes
7050235
70b1dc5
d65402d
 
7050235
 
d65402d
 
 
7981cc4
d65402d
 
 
 
 
 
7981cc4
 
d65402d
7050235
7981cc4
 
 
d65402d
 
7050235
d65402d
7981cc4
7050235
d65402d
70b1dc5
7050235
7981cc4
 
 
 
d65402d
71501f9
7981cc4
d65402d
 
 
 
7050235
d65402d
7981cc4
71501f9
d65402d
 
 
 
 
7981cc4
71501f9
7981cc4
71501f9
7981cc4
 
 
 
71501f9
 
d65402d
7981cc4
d65402d
7981cc4
d65402d
7981cc4
d65402d
7050235
 
d65402d
 
7981cc4
d65402d
 
 
 
7981cc4
7050235
d65402d
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
import cv2
import textwrap
from PIL import Image, ImageDraw, ImageFont
import numpy as np


def add_text(
    image,
    text,
    contour,
    font_path,
    initial_font_size=42,
    padding=10,
    line_spacing=1.25
):
    """
    Renderiza texto dentro de uma bolha usando o CONTOUR como referência.
    Prioriza quebra de linhas antes de reduzir a fonte.
    """

    # --- Extrai bounding box do contorno ---
    x, y, w, h = cv2.boundingRect(contour)

    img_pil = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(img_pil)

    font_size = initial_font_size
    wrapping_ratio = 0.9

    while font_size > 10:
        font = ImageFont.truetype(font_path, font_size)

        max_chars_per_line = max(
            1, int((w - 2 * padding) / (font_size * wrapping_ratio))
        )

        lines = textwrap.wrap(text, width=max_chars_per_line)

        # Evita linha única quando há espaço vertical
        min_lines = 2 if h > font_size * 2.5 else 1
        if len(lines) < min_lines:
            wrapping_ratio -= 0.03
            continue

        max_line_width = 0
        total_height = 0

        for line in lines:
            bbox_text = draw.textbbox((0, 0), line, font=font)
            lw = bbox_text[2] - bbox_text[0]
            lh = bbox_text[3] - bbox_text[1]
            max_line_width = max(max_line_width, lw)
            total_height += lh

        total_height = int(total_height * line_spacing)

        if (
            total_height <= (h - 2 * padding)
            and max_line_width <= (w - 2 * padding)
        ):
            break

        if max_line_width > (w - 2 * padding):
            wrapping_ratio -= 0.02
        else:
            font_size -= 1

    # --- Centralização ---
    current_y = y + padding + (h - total_height) // 2

    for line in lines:
        bbox_text = draw.textbbox((0, 0), line, font=font)
        lw = bbox_text[2] - bbox_text[0]
        lh = bbox_text[3] - bbox_text[1]

        text_x = x + (w - lw) // 2
        draw.text((text_x, current_y), line, fill=(0, 0, 0), font=font)

        current_y += int(lh * line_spacing)

    return cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)