maggidev commited on
Commit
d65402d
·
verified ·
1 Parent(s): 71501f9

Update add_text.py

Browse files
Files changed (1) hide show
  1. add_text.py +56 -35
add_text.py CHANGED
@@ -1,54 +1,75 @@
1
- from PIL import Image, ImageDraw, ImageFont
2
- import numpy as np
3
  import cv2
4
  import textwrap
 
 
5
 
6
 
7
- def add_text(image, text, font_path, bubble_contour):
8
- pil_image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
9
- draw = ImageDraw.Draw(pil_image)
 
 
 
 
 
 
 
 
 
 
10
 
11
- x, y, w, h = cv2.boundingRect(bubble_contour)
 
 
12
 
13
- # Tamanho inicial baseado na bolha
14
- font_size = max(12, int(h * 0.08))
15
- wrapping_ratio = 0.09
16
 
17
- while True:
18
  font = ImageFont.truetype(font_path, font_size)
19
- line_height = int(font_size * 1.2)
20
 
21
- wrapped_text = textwrap.fill(
22
- text,
23
- width=max(1, int(w * wrapping_ratio)),
24
- break_long_words=True
25
- )
26
 
27
- lines = wrapped_text.split("\n")
28
- total_height = len(lines) * line_height
 
 
 
29
 
30
- # 🔍 Verificação REAL de largura em pixels
31
- max_line_width = max(
32
- draw.textlength(line, font=font) for line in lines
33
- )
34
 
35
- if total_height <= h and max_line_width <= w:
36
- break
 
 
 
 
37
 
38
- # Ajustes progressivos
39
- font_size -= 1
40
- wrapping_ratio += 0.015
41
 
42
- if font_size <= 10:
 
43
  break
44
 
45
- # Centralização vertical
46
- text_y = y + (h - total_height) // 2
 
 
 
 
 
 
47
 
48
  for line in lines:
49
- line_width = draw.textlength(line, font=font)
50
- text_x = x + (w - line_width) // 2
51
- draw.text((text_x, text_y), line, fill=(0, 0, 0), font=font)
52
- text_y += line_height
 
 
 
53
 
54
- return cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR)
 
 
 
1
  import cv2
2
  import textwrap
3
+ from PIL import Image, ImageDraw, ImageFont
4
+ import numpy as np
5
 
6
 
7
+ def add_text(
8
+ image,
9
+ text,
10
+ bbox,
11
+ font_path,
12
+ initial_font_size=42,
13
+ padding=10,
14
+ line_spacing=1.25
15
+ ):
16
+ """
17
+ Insere texto dentro de uma bolha respeitando largura, altura e estética tipográfica.
18
+ Prioriza quebra de linhas antes de reduzir drasticamente o tamanho da fonte.
19
+ """
20
 
21
+ x, y, w, h = bbox
22
+ img_pil = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
23
+ draw = ImageDraw.Draw(img_pil)
24
 
25
+ font_size = initial_font_size
26
+ wrapping_ratio = 0.9 # começa permitindo múltiplas linhas
 
27
 
28
+ while font_size > 10:
29
  font = ImageFont.truetype(font_path, font_size)
 
30
 
31
+ max_chars_per_line = max(1, int((w - 2 * padding) / (font_size * wrapping_ratio)))
32
+ lines = textwrap.wrap(text, width=max_chars_per_line)
 
 
 
33
 
34
+ # --- REGRA CRÍTICA: NÃO PERMITIR LINHA ÚNICA SE HOUVER ALTURA ---
35
+ min_lines = 2 if h > font_size * 2.5 else 1
36
+ if len(lines) < min_lines:
37
+ wrapping_ratio -= 0.03
38
+ continue
39
 
40
+ # Medições reais
41
+ line_heights = []
42
+ max_line_width = 0
 
43
 
44
+ for line in lines:
45
+ bbox_text = draw.textbbox((0, 0), line, font=font)
46
+ lw = bbox_text[2] - bbox_text[0]
47
+ lh = bbox_text[3] - bbox_text[1]
48
+ max_line_width = max(max_line_width, lw)
49
+ line_heights.append(lh)
50
 
51
+ total_height = int(sum(line_heights) * line_spacing)
 
 
52
 
53
+ # --- VERIFICA ENCAIXE ---
54
+ if total_height <= (h - 2 * padding) and max_line_width <= (w - 2 * padding):
55
  break
56
 
57
+ # --- PRIORIDADE CORRETA ---
58
+ if max_line_width > (w - 2 * padding):
59
+ wrapping_ratio -= 0.02 # quebra mais linhas
60
+ else:
61
+ font_size -= 1 # só reduz fonte se necessário
62
+
63
+ # --- DESENHO FINAL ---
64
+ current_y = y + padding + (h - total_height) // 2
65
 
66
  for line in lines:
67
+ bbox_text = draw.textbbox((0, 0), line, font=font)
68
+ lw = bbox_text[2] - bbox_text[0]
69
+
70
+ text_x = x + (w - lw) // 2
71
+ draw.text((text_x, current_y), line, fill=(0, 0, 0), font=font)
72
+
73
+ current_y += int((bbox_text[3] - bbox_text[1]) * line_spacing)
74
 
75
+ return cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)