VirtualOasis commited on
Commit
583daf5
·
verified ·
1 Parent(s): 9b64245

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +12 -38
app.py CHANGED
@@ -1,6 +1,5 @@
1
  import os
2
  import gradio as gr
3
- import tempfile
4
  from PIL import Image, ImageDraw, ImageFont
5
 
6
  # --- Image Generation Logic (from coverter.py) ---
@@ -28,8 +27,8 @@ def draw_lattice_grid(draw, width, height, spacing=100, color=(235, 235, 235)):
28
 
29
  def text_to_images_generator(text_content, style='lines', font_path=None):
30
  """
31
- Converts a given string of text into a series of images and returns their file paths.
32
- This version is adapted for Gradio to return image paths from a temporary directory.
33
 
34
  Args:
35
  text_content (str): The text to be converted.
@@ -37,7 +36,7 @@ def text_to_images_generator(text_content, style='lines', font_path=None):
37
  font_path (str, optional): The path to a .ttf font file.
38
 
39
  Returns:
40
- list: A list of file paths for the generated images.
41
  """
42
  if not text_content or not text_content.strip():
43
  # Return empty list and show a warning if there is no text
@@ -57,17 +56,12 @@ def text_to_images_generator(text_content, style='lines', font_path=None):
57
  FONT_SIZE = 48
58
  LINE_SPACING = 20
59
 
60
- # Create a temporary directory to save images for the Gradio gallery
61
- output_dir = tempfile.mkdtemp()
62
-
63
  # --- Font Loading ---
64
  font = None
65
  try:
66
- # Prioritize provided font path if it exists
67
  if font_path and os.path.exists(font_path):
68
  font = ImageFont.truetype(font_path, FONT_SIZE)
69
  else:
70
- # Otherwise, search for common system fonts
71
  font_paths_to_try = [
72
  "Arial.ttf", "arial.ttf", "DejaVuSans.ttf",
73
  "/System/Library/Fonts/Supplemental/Arial.ttf",
@@ -80,9 +74,8 @@ def text_to_images_generator(text_content, style='lines', font_path=None):
80
  break
81
  except IOError:
82
  continue
83
- # Fallback to default if no font is found
84
  if not font:
85
- gr.Warning("Could not find a standard .ttf font. Falling back to the basic default font. Text may look pixelated.")
86
  font = ImageFont.load_default()
87
  except Exception as e:
88
  print(f"An unexpected error occurred during font loading: {e}")
@@ -97,7 +90,6 @@ def text_to_images_generator(text_content, style='lines', font_path=None):
97
  words = paragraph.split()
98
  current_line = ""
99
  for word in words:
100
- # Handle very long words by breaking them up
101
  if font.getlength(word) > drawable_width:
102
  temp_word = ""
103
  for char in word:
@@ -115,31 +107,26 @@ def text_to_images_generator(text_content, style='lines', font_path=None):
115
  current_line = word
116
  all_lines_and_breaks.append(current_line.strip())
117
 
118
- # Add a placeholder for paragraph breaks
119
  if i < len(paragraphs) - 1:
120
  all_lines_and_breaks.append(None)
121
 
122
  # --- Image Generation ---
123
- generated_files = []
124
- img_count = 0
125
  page_content = []
126
  y_text = PADDING_Y
127
 
128
  try:
129
- # Get line height from font metrics if possible
130
  line_height = font.getbbox("A")[3] - font.getbbox("A")[1]
131
  except AttributeError:
132
- # Fallback for default font
133
  line_height = 12
134
 
135
  PARAGRAPH_SPACING = line_height
136
 
137
- def create_image_page(content, page_num):
138
- """Helper function to create and save a single image page."""
139
  img = Image.new('RGB', (IMG_WIDTH, IMG_HEIGHT), color=BACKGROUND_COLOR)
140
  draw = ImageDraw.Draw(img)
141
 
142
- # Draw the selected background style first
143
  if style == 'lines':
144
  line_style_spacing = line_height + LINE_SPACING
145
  draw_horizontal_lines(draw, IMG_WIDTH, IMG_HEIGHT, spacing=line_style_spacing, color=STYLE_COLOR)
@@ -148,50 +135,39 @@ def text_to_images_generator(text_content, style='lines', font_path=None):
148
  elif style == 'grid':
149
  draw_lattice_grid(draw, IMG_WIDTH, IMG_HEIGHT, color=STYLE_COLOR)
150
 
151
- # Draw the text on top of the background
152
  current_y = PADDING_Y
153
  for page_item in content:
154
  if page_item is not None:
155
  draw.text((PADDING_X, current_y), page_item, font=font, fill=TEXT_COLOR)
156
  current_y += line_height + LINE_SPACING
157
- else: # This is a paragraph break
158
  current_y += PARAGRAPH_SPACING
159
 
160
- filename = os.path.join(output_dir, f"page_{page_num}.png")
161
- img.save(filename)
162
- generated_files.append(filename)
163
 
164
- # Iterate through all lines and create pages
165
  for item in all_lines_and_breaks:
166
  is_break = item is None
167
  item_height = PARAGRAPH_SPACING if is_break else line_height
168
 
169
- # If adding the next line/break exceeds page height, create the current page
170
  if y_text + item_height > IMG_HEIGHT - PADDING_Y:
171
- img_count += 1
172
- create_image_page(page_content, img_count)
173
- # Start a new page
174
  page_content = [item]
175
  y_text = PADDING_Y + item_height + (0 if is_break else LINE_SPACING)
176
  else:
177
  page_content.append(item)
178
  y_text += item_height + (0 if is_break else LINE_SPACING)
179
 
180
- # Save the last page if it has content
181
  if page_content:
182
- img_count += 1
183
- create_image_page(page_content, img_count)
184
 
185
- return generated_files
186
 
187
  # --- Gradio Interface ---
188
 
189
- # Example text to pre-fill the textbox
190
  example_text = """In the heart of a bustling city, there lived a clockmaker named Alistair. His shop, a quaint corner of tranquility amidst the urban chaos, was filled with the gentle ticking of countless timepieces. Each clock was a masterpiece, a testament to his dedication and skill.
191
 
192
  One day, a young girl with eyes as curious as a cat's wandered into his shop. She wasn't interested in the shiny new watches but was drawn to the grandfather clock in the corner. "What's its story?" she asked, her voice soft. Alistair smiled, for he knew he had found the next guardian of the stories. The legacy of the whispering clock would live on."""
193
 
194
- # Define the Gradio interface
195
  demo = gr.Interface(
196
  fn=text_to_images_generator,
197
  inputs=[
@@ -206,6 +182,4 @@ demo = gr.Interface(
206
 
207
  # --- Main Execution ---
208
  if __name__ == "__main__":
209
- # Launch the Gradio app as an MCP server
210
- # The MCP server allows other applications to call this Gradio app as an API
211
  demo.launch(mcp_server=True)
 
1
  import os
2
  import gradio as gr
 
3
  from PIL import Image, ImageDraw, ImageFont
4
 
5
  # --- Image Generation Logic (from coverter.py) ---
 
27
 
28
  def text_to_images_generator(text_content, style='lines', font_path=None):
29
  """
30
+ Converts a given string of text into a series of images and returns them
31
+ as a list of PIL Image objects. This is compatible with both UI and MCP.
32
 
33
  Args:
34
  text_content (str): The text to be converted.
 
36
  font_path (str, optional): The path to a .ttf font file.
37
 
38
  Returns:
39
+ list: A list of PIL.Image.Image objects.
40
  """
41
  if not text_content or not text_content.strip():
42
  # Return empty list and show a warning if there is no text
 
56
  FONT_SIZE = 48
57
  LINE_SPACING = 20
58
 
 
 
 
59
  # --- Font Loading ---
60
  font = None
61
  try:
 
62
  if font_path and os.path.exists(font_path):
63
  font = ImageFont.truetype(font_path, FONT_SIZE)
64
  else:
 
65
  font_paths_to_try = [
66
  "Arial.ttf", "arial.ttf", "DejaVuSans.ttf",
67
  "/System/Library/Fonts/Supplemental/Arial.ttf",
 
74
  break
75
  except IOError:
76
  continue
 
77
  if not font:
78
+ gr.Warning("Could not find a standard .ttf font. Falling back to the basic default font.")
79
  font = ImageFont.load_default()
80
  except Exception as e:
81
  print(f"An unexpected error occurred during font loading: {e}")
 
90
  words = paragraph.split()
91
  current_line = ""
92
  for word in words:
 
93
  if font.getlength(word) > drawable_width:
94
  temp_word = ""
95
  for char in word:
 
107
  current_line = word
108
  all_lines_and_breaks.append(current_line.strip())
109
 
 
110
  if i < len(paragraphs) - 1:
111
  all_lines_and_breaks.append(None)
112
 
113
  # --- Image Generation ---
114
+ generated_images = [] # Store PIL Image objects directly
 
115
  page_content = []
116
  y_text = PADDING_Y
117
 
118
  try:
 
119
  line_height = font.getbbox("A")[3] - font.getbbox("A")[1]
120
  except AttributeError:
 
121
  line_height = 12
122
 
123
  PARAGRAPH_SPACING = line_height
124
 
125
+ def create_image_page(content):
126
+ """Helper function to create a single image page and return it."""
127
  img = Image.new('RGB', (IMG_WIDTH, IMG_HEIGHT), color=BACKGROUND_COLOR)
128
  draw = ImageDraw.Draw(img)
129
 
 
130
  if style == 'lines':
131
  line_style_spacing = line_height + LINE_SPACING
132
  draw_horizontal_lines(draw, IMG_WIDTH, IMG_HEIGHT, spacing=line_style_spacing, color=STYLE_COLOR)
 
135
  elif style == 'grid':
136
  draw_lattice_grid(draw, IMG_WIDTH, IMG_HEIGHT, color=STYLE_COLOR)
137
 
 
138
  current_y = PADDING_Y
139
  for page_item in content:
140
  if page_item is not None:
141
  draw.text((PADDING_X, current_y), page_item, font=font, fill=TEXT_COLOR)
142
  current_y += line_height + LINE_SPACING
143
+ else:
144
  current_y += PARAGRAPH_SPACING
145
 
146
+ generated_images.append(img) # Add the PIL image to our list
 
 
147
 
 
148
  for item in all_lines_and_breaks:
149
  is_break = item is None
150
  item_height = PARAGRAPH_SPACING if is_break else line_height
151
 
 
152
  if y_text + item_height > IMG_HEIGHT - PADDING_Y:
153
+ create_image_page(page_content)
 
 
154
  page_content = [item]
155
  y_text = PADDING_Y + item_height + (0 if is_break else LINE_SPACING)
156
  else:
157
  page_content.append(item)
158
  y_text += item_height + (0 if is_break else LINE_SPACING)
159
 
 
160
  if page_content:
161
+ create_image_page(page_content)
 
162
 
163
+ return generated_images
164
 
165
  # --- Gradio Interface ---
166
 
 
167
  example_text = """In the heart of a bustling city, there lived a clockmaker named Alistair. His shop, a quaint corner of tranquility amidst the urban chaos, was filled with the gentle ticking of countless timepieces. Each clock was a masterpiece, a testament to his dedication and skill.
168
 
169
  One day, a young girl with eyes as curious as a cat's wandered into his shop. She wasn't interested in the shiny new watches but was drawn to the grandfather clock in the corner. "What's its story?" she asked, her voice soft. Alistair smiled, for he knew he had found the next guardian of the stories. The legacy of the whispering clock would live on."""
170
 
 
171
  demo = gr.Interface(
172
  fn=text_to_images_generator,
173
  inputs=[
 
182
 
183
  # --- Main Execution ---
184
  if __name__ == "__main__":
 
 
185
  demo.launch(mcp_server=True)