ArrcttacsrjksX commited on
Commit
5a1461e
·
verified ·
1 Parent(s): 70bdc4c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -11
app.py CHANGED
@@ -9,7 +9,6 @@ import math
9
  import tempfile
10
  from pathlib import Path
11
 
12
- # Thêm các font phổ biến
13
  COMMON_FONTS = [
14
  "Times New Roman",
15
  "Arial",
@@ -27,17 +26,14 @@ def get_system_fonts():
27
  fonts = []
28
  common_fonts_found = []
29
 
30
- # Lấy tất cả font trong hệ thống
31
  for font in matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf'):
32
  font_name = os.path.basename(font)
33
  actual_name = matplotlib.font_manager.FontProperties(fname=font).get_name()
34
 
35
- # Kiểm tra nếu là font phổ biến
36
  if any(common_font.lower() in actual_name.lower() for common_font in COMMON_FONTS):
37
  common_fonts_found.append((font_name, font))
38
  fonts.append((font_name, font))
39
 
40
- # Sắp xếp để font phổ biến lên đầu
41
  sorted_fonts = sorted(common_fonts_found, key=lambda x: COMMON_FONTS.index(
42
  next(cf for cf in COMMON_FONTS if cf.lower() in matplotlib.font_manager.FontProperties(fname=x[1]).get_name().lower())
43
  ))
@@ -45,17 +41,57 @@ def get_system_fonts():
45
 
46
  return [f[0] for f in sorted_fonts], {f[0]: f[1] for f in sorted_fonts}
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  def save_image_to_file(img, format="PNG"):
49
- # Tạo temporary file
50
  temp_dir = Path(tempfile.gettempdir())
51
  temp_file = temp_dir / f"text_image.{format.lower()}"
52
 
53
- # Lưu ảnh
54
  img.save(temp_file, format=format)
55
  return str(temp_file)
56
 
57
- [Previous functions remain the same: parse_color, calculate_text_dimensions, create_text_segment, render_math_image]
58
-
59
  def render_plain_text_image(text, font_size, width, height, bg_color, text_color, font_name, align):
60
  bg_color = parse_color(bg_color)
61
  text_color = parse_color(text_color)
@@ -67,7 +103,50 @@ def render_plain_text_image(text, font_size, width, height, bg_color, text_color
67
  except Exception:
68
  font = ImageFont.load_default()
69
 
70
- [Rest of the function remains the same]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
  def text_to_image(input_text, font_size, width, height, bg_color, text_color,
73
  mode, font_name, align, image_format, preview_mode):
@@ -82,7 +161,6 @@ def text_to_image(input_text, font_size, width, height, bg_color, text_color,
82
  if preview_mode:
83
  return img
84
  else:
85
- # Return file path for download
86
  return save_image_to_file(img, image_format)
87
 
88
  def handle_file_upload(file, font_size, width, height, bg_color, text_color,
@@ -95,7 +173,6 @@ def handle_file_upload(file, font_size, width, height, bg_color, text_color,
95
  mode, font_name, align, image_format, preview_mode)
96
  return "No file uploaded!"
97
 
98
- # Get fonts and create font paths dictionary
99
  font_list, FONT_PATHS = get_system_fonts()
100
  default_font = next((f for f in font_list if "times" in f.lower()
101
  or "arial" in f.lower()), font_list[0])
 
9
  import tempfile
10
  from pathlib import Path
11
 
 
12
  COMMON_FONTS = [
13
  "Times New Roman",
14
  "Arial",
 
26
  fonts = []
27
  common_fonts_found = []
28
 
 
29
  for font in matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf'):
30
  font_name = os.path.basename(font)
31
  actual_name = matplotlib.font_manager.FontProperties(fname=font).get_name()
32
 
 
33
  if any(common_font.lower() in actual_name.lower() for common_font in COMMON_FONTS):
34
  common_fonts_found.append((font_name, font))
35
  fonts.append((font_name, font))
36
 
 
37
  sorted_fonts = sorted(common_fonts_found, key=lambda x: COMMON_FONTS.index(
38
  next(cf for cf in COMMON_FONTS if cf.lower() in matplotlib.font_manager.FontProperties(fname=x[1]).get_name().lower())
39
  ))
 
41
 
42
  return [f[0] for f in sorted_fonts], {f[0]: f[1] for f in sorted_fonts}
43
 
44
+ def parse_color(color):
45
+ if isinstance(color, str) and color.startswith('rgba'):
46
+ color = color.replace('rgba', '').strip('()').split(',')
47
+ return tuple(int(float(c.strip())) for c in color[:3])
48
+ return color
49
+
50
+ def calculate_text_dimensions(text, font, max_width, margin):
51
+ lines = []
52
+ for line in text.split('\n'):
53
+ lines.extend(textwrap.wrap(line, width=int(max_width / font.size * 1.8)))
54
+
55
+ bbox = font.getbbox('Ay')
56
+ line_height = bbox[3] - bbox[1]
57
+ total_height = line_height * len(lines)
58
+
59
+ return lines, line_height, total_height
60
+
61
+ def create_text_segment(lines, start_idx, max_lines, width, height, bg_color, text_color, font, align, margin):
62
+ img = Image.new("RGB", (width, height), color=bg_color)
63
+ draw = ImageDraw.Draw(img)
64
+
65
+ bbox = font.getbbox('Ay')
66
+ line_height = bbox[3] - bbox[1]
67
+
68
+ y = margin
69
+ end_idx = min(start_idx + max_lines, len(lines))
70
+ segment_lines = lines[start_idx:end_idx]
71
+
72
+ for line in segment_lines:
73
+ bbox = font.getbbox(line)
74
+ line_width = bbox[2] - bbox[0]
75
+
76
+ if align == 'Left':
77
+ x = margin
78
+ elif align == 'Center':
79
+ x = (width - line_width) // 2
80
+ else: # Right alignment
81
+ x = width - line_width - margin
82
+
83
+ draw.text((x, y), line, fill=text_color, font=font)
84
+ y += line_height
85
+
86
+ return img, end_idx
87
+
88
  def save_image_to_file(img, format="PNG"):
 
89
  temp_dir = Path(tempfile.gettempdir())
90
  temp_file = temp_dir / f"text_image.{format.lower()}"
91
 
 
92
  img.save(temp_file, format=format)
93
  return str(temp_file)
94
 
 
 
95
  def render_plain_text_image(text, font_size, width, height, bg_color, text_color, font_name, align):
96
  bg_color = parse_color(bg_color)
97
  text_color = parse_color(text_color)
 
103
  except Exception:
104
  font = ImageFont.load_default()
105
 
106
+ max_width = width - 2 * margin
107
+ lines, line_height, total_text_height = calculate_text_dimensions(text, font, max_width, margin)
108
+
109
+ max_lines_per_segment = (height - 2 * margin) // line_height
110
+ num_segments = math.ceil(len(lines) / max_lines_per_segment)
111
+
112
+ segments = []
113
+ current_line = 0
114
+
115
+ for i in range(num_segments):
116
+ segment_img, current_line = create_text_segment(
117
+ lines, current_line, max_lines_per_segment,
118
+ width, height, bg_color, text_color, font, align, margin
119
+ )
120
+ segments.append(segment_img)
121
+
122
+ total_height = len(segments) * height
123
+ final_image = Image.new("RGB", (width, total_height), color=bg_color)
124
+
125
+ for i, segment in enumerate(segments):
126
+ final_image.paste(segment, (0, i * height))
127
+
128
+ return final_image
129
+
130
+ def render_math_image(text, font_size, width, height, bg_color, text_color):
131
+ bg_color = parse_color(bg_color)
132
+ text_color = parse_color(text_color)
133
+
134
+ fig, ax = plt.subplots(figsize=(width / 100, height / 100), facecolor=bg_color)
135
+ ax.set_facecolor(bg_color)
136
+ ax.axis('off')
137
+
138
+ if not (text.startswith(r"$") and text.endswith(r"$")):
139
+ text = rf"${text}$"
140
+
141
+ ax.text(0.5, 0.5, text, fontsize=font_size, ha='center', va='center', color=text_color)
142
+
143
+ buf = BytesIO()
144
+ plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0)
145
+ plt.close(fig)
146
+
147
+ buf.seek(0)
148
+ img = Image.open(buf)
149
+ return img
150
 
151
  def text_to_image(input_text, font_size, width, height, bg_color, text_color,
152
  mode, font_name, align, image_format, preview_mode):
 
161
  if preview_mode:
162
  return img
163
  else:
 
164
  return save_image_to_file(img, image_format)
165
 
166
  def handle_file_upload(file, font_size, width, height, bg_color, text_color,
 
173
  mode, font_name, align, image_format, preview_mode)
174
  return "No file uploaded!"
175
 
 
176
  font_list, FONT_PATHS = get_system_fonts()
177
  default_font = next((f for f in font_list if "times" in f.lower()
178
  or "arial" in f.lower()), font_list[0])