ArrcttacsrjksX commited on
Commit
70bdc4c
·
verified ·
1 Parent(s): 4e763f3

Upload app (6).py

Browse files
Files changed (1) hide show
  1. app (6).py +192 -0
app (6).py ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import matplotlib.pyplot as plt
3
+ from io import BytesIO
4
+ from PIL import Image, ImageDraw, ImageFont
5
+ import textwrap
6
+ import os
7
+ import matplotlib
8
+ import math
9
+
10
+ def get_system_fonts():
11
+ fonts = []
12
+ for font in matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf'):
13
+ font_name = os.path.basename(font)
14
+ fonts.append(font_name)
15
+ return sorted(set(fonts))
16
+
17
+ def parse_color(color):
18
+ if isinstance(color, str) and color.startswith('rgba'):
19
+ color = color.replace('rgba', '').strip('()').split(',')
20
+ return tuple(int(float(c.strip())) for c in color[:3])
21
+ return color
22
+
23
+ def calculate_text_dimensions(text, font, max_width, margin):
24
+ lines = []
25
+ for line in text.split('\n'):
26
+ lines.extend(textwrap.wrap(line, width=int(max_width / font.size * 1.8)))
27
+
28
+ bbox = font.getbbox('Ay')
29
+ line_height = bbox[3] - bbox[1]
30
+ total_height = line_height * len(lines)
31
+
32
+ return lines, line_height, total_height
33
+
34
+ def create_text_segment(lines, start_idx, max_lines, width, height, bg_color, text_color, font, align, margin):
35
+ img = Image.new("RGB", (width, height), color=bg_color)
36
+ draw = ImageDraw.Draw(img)
37
+
38
+ bbox = font.getbbox('Ay')
39
+ line_height = bbox[3] - bbox[1]
40
+
41
+ y = margin
42
+ end_idx = min(start_idx + max_lines, len(lines))
43
+ segment_lines = lines[start_idx:end_idx]
44
+
45
+ for line in segment_lines:
46
+ bbox = font.getbbox(line)
47
+ line_width = bbox[2] - bbox[0]
48
+
49
+ if align == 'Left':
50
+ x = margin
51
+ elif align == 'Center':
52
+ x = (width - line_width) // 2
53
+ else: # Right alignment
54
+ x = width - line_width - margin
55
+
56
+ draw.text((x, y), line, fill=text_color, font=font)
57
+ y += line_height
58
+
59
+ return img, end_idx
60
+
61
+ def render_plain_text_image(text, font_size, width, height, bg_color, text_color, font_name, align):
62
+ bg_color = parse_color(bg_color)
63
+ text_color = parse_color(text_color)
64
+ margin = 10
65
+
66
+ try:
67
+ font_path = matplotlib.font_manager.findfont(font_name)
68
+ font = ImageFont.truetype(font_path, font_size)
69
+ except Exception:
70
+ font = ImageFont.load_default()
71
+
72
+ # Calculate dimensions
73
+ max_width = width - 2 * margin
74
+ lines, line_height, total_text_height = calculate_text_dimensions(text, font, max_width, margin)
75
+
76
+ # Calculate how many lines can fit in one segment
77
+ max_lines_per_segment = (height - 2 * margin) // line_height
78
+
79
+ # Calculate number of segments needed
80
+ num_segments = math.ceil(len(lines) / max_lines_per_segment)
81
+
82
+ # Create segments
83
+ segments = []
84
+ current_line = 0
85
+
86
+ for i in range(num_segments):
87
+ segment_img, current_line = create_text_segment(
88
+ lines, current_line, max_lines_per_segment,
89
+ width, height, bg_color, text_color, font, align, margin
90
+ )
91
+ segments.append(segment_img)
92
+
93
+ # Combine all segments vertically
94
+ total_height = len(segments) * height
95
+ final_image = Image.new("RGB", (width, total_height), color=bg_color)
96
+
97
+ for i, segment in enumerate(segments):
98
+ final_image.paste(segment, (0, i * height))
99
+
100
+ return final_image
101
+
102
+ def render_math_image(text, font_size, width, height, bg_color, text_color):
103
+ bg_color = parse_color(bg_color)
104
+ text_color = parse_color(text_color)
105
+
106
+ fig, ax = plt.subplots(figsize=(width / 100, height / 100), facecolor=bg_color)
107
+ ax.set_facecolor(bg_color)
108
+ ax.axis('off')
109
+
110
+ if not (text.startswith(r"$") and text.endswith(r"$")):
111
+ text = rf"${text}$"
112
+
113
+ ax.text(0.5, 0.5, text, fontsize=font_size, ha='center', va='center', color=text_color)
114
+
115
+ buf = BytesIO()
116
+ plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0)
117
+ plt.close(fig)
118
+
119
+ buf.seek(0)
120
+ img = Image.open(buf)
121
+ return img
122
+
123
+ def text_to_image(input_text, font_size, width, height, bg_color, text_color, mode, font_name, align, image_format):
124
+ if mode == "Plain Text":
125
+ img = render_plain_text_image(input_text, font_size, width, height, bg_color, text_color, font_name, align)
126
+ elif mode == "LaTeX Math":
127
+ img = render_math_image(input_text, font_size, width, height, bg_color, text_color)
128
+ else:
129
+ return "Invalid mode selected!"
130
+
131
+ return img
132
+
133
+ def handle_file_upload(file, font_size, width, height, bg_color, text_color, mode, font_name, align, image_format):
134
+ if file is not None:
135
+ file_path = file[0]
136
+ with open(file_path, "r", encoding="utf-8") as f:
137
+ text = f.read()
138
+ return text_to_image(text, font_size, width, height, bg_color, text_color, mode, font_name, align, image_format)
139
+ return "No file uploaded!"
140
+
141
+ font_list = get_system_fonts()
142
+ default_font = "DejaVuSans.ttf" if "DejaVuSans.ttf" in font_list else font_list[0]
143
+
144
+ with gr.Blocks() as demo:
145
+ gr.Markdown("# 🖼️ Text to Image Converter")
146
+
147
+ with gr.Row():
148
+ input_text = gr.Textbox(label="Enter Text", placeholder="Type or paste text here...", lines=5)
149
+ file_input = gr.File(label="Upload a Text File", type="filepath")
150
+
151
+ with gr.Row():
152
+ font_size = gr.Slider(10, 100, value=30, label="Font Size")
153
+ font_name = gr.Dropdown(choices=font_list, value=default_font, label="Font")
154
+ align = gr.Radio(["Left", "Center", "Right"], label="Text Alignment", value="Center")
155
+
156
+ with gr.Row():
157
+ width = gr.Slider(200, 2000, value=800, label="Image Width")
158
+ height = gr.Slider(200, 2000, value=600, label="Base Height")
159
+
160
+ with gr.Row():
161
+ bg_color = gr.ColorPicker(label="Background Color", value="#FFFFFF")
162
+ text_color = gr.ColorPicker(label="Text Color", value="#000000")
163
+
164
+ with gr.Row():
165
+ mode = gr.Radio(["Plain Text", "LaTeX Math"], label="Rendering Mode", value="Plain Text")
166
+ image_format = gr.Radio(["PNG", "JPEG"], label="Image Format", value="PNG")
167
+
168
+ output_image = gr.Image(label="Generated Image")
169
+
170
+ with gr.Row():
171
+ convert_button = gr.Button("Convert Text to Image")
172
+ file_convert_button = gr.Button("Convert File to Image")
173
+
174
+ convert_button.click(
175
+ text_to_image,
176
+ inputs=[
177
+ input_text, font_size, width, height, bg_color, text_color,
178
+ mode, font_name, align, image_format
179
+ ],
180
+ outputs=output_image
181
+ )
182
+
183
+ file_convert_button.click(
184
+ handle_file_upload,
185
+ inputs=[
186
+ file_input, font_size, width, height, bg_color, text_color,
187
+ mode, font_name, align, image_format
188
+ ],
189
+ outputs=output_image
190
+ )
191
+
192
+ demo.launch()