bakyt92 commited on
Commit
6114732
·
1 Parent(s): 3e2a06d

Adding logs

Browse files
Files changed (1) hide show
  1. app.py +184 -84
app.py CHANGED
@@ -75,102 +75,191 @@ def process_uploaded_image(image):
75
  # Text Overlay Functions
76
  def add_text_to_image(img, pattern, line1, line2, line3, font_size, color):
77
  """Overlay 2- or 3-line text on the image in a preset layout."""
 
 
 
 
 
 
 
78
  if img is None:
 
79
  return None, "Please supply an image first."
80
 
81
- # Create a working copy
82
- image = img.convert("RGB") # Ensure RGB mode
83
- draw = ImageDraw.Draw(image)
84
-
85
- # More robust font loading with better fallbacks
86
- font = None
87
- font_paths = [
88
- "DejaVuSans-Bold.ttf",
89
- "arial.ttf",
90
- "/System/Library/Fonts/Arial.ttf",
91
- "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
92
- "/usr/share/fonts/TTF/arial.ttf",
93
- ]
94
-
95
- for font_path in font_paths:
96
- try:
97
- font = ImageFont.truetype(font_path, font_size)
98
- break
99
- except (OSError, IOError):
100
- continue
101
-
102
- # Final fallback to default font
103
- if font is None:
104
- try:
105
- font = ImageFont.load_default()
106
- except Exception:
107
- # Create a basic font if all else fails
108
- font = ImageFont.load_default()
109
 
110
- w, h = image.size
111
- positions = []
112
-
113
- # Define text positioning patterns
114
- if pattern == "2-lines-top":
115
- positions = [(w // 2, int(h * 0.10)), (w // 2, int(h * 0.20))]
116
- elif pattern == "2-lines-bottom":
117
- positions = [(w // 2, int(h * 0.80)), (w // 2, int(h * 0.90))]
118
- elif pattern == "2-lines-center":
119
- positions = [(w // 2, int(h * 0.45)), (w // 2, int(h * 0.55))]
120
- elif pattern == "3-lines-center":
121
- positions = [(w // 2, int(h * 0.40)), (w // 2, int(h * 0.50)), (w // 2, int(h * 0.60))]
122
- elif pattern == "3-lines-top":
123
- positions = [(w // 2, int(h * 0.10)), (w // 2, int(h * 0.20)), (w // 2, int(h * 0.30))]
124
- elif pattern == "3-lines-bottom":
125
- positions = [(w // 2, int(h * 0.70)), (w // 2, int(h * 0.80)), (w // 2, int(h * 0.90))]
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
- # Convert hex color to RGB tuple if needed
128
- if isinstance(color, str) and color.startswith('#'):
129
- # Convert hex to RGB
130
- color = color.lstrip('#')
131
- if len(color) == 6:
132
- color = tuple(int(color[i:i+2], 16) for i in (0, 2, 4))
 
 
 
 
 
 
 
 
 
 
 
133
  else:
134
- color = (255, 255, 255) # Default to white
135
-
136
- # Draw text with better visibility
137
- lines = [line1, line2, line3][:len(positions)]
138
- text_drawn = False
139
-
140
- for (x, y), txt in zip(positions, lines):
141
- if txt and txt.strip():
142
- # Add text stroke/outline for better visibility
143
- stroke_width = max(1, font_size // 20)
144
 
145
- # Draw text outline (black)
146
- for dx in [-stroke_width, 0, stroke_width]:
147
- for dy in [-stroke_width, 0, stroke_width]:
148
- if dx != 0 or dy != 0:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  try:
150
- draw.text((x + dx, y + dy), txt, fill=(0, 0, 0), font=font, anchor="mm")
151
- except TypeError:
152
- # Fallback for older PIL versions without anchor
153
  bbox = draw.textbbox((0, 0), txt, font=font)
154
  text_w = bbox[2] - bbox[0]
155
  text_h = bbox[3] - bbox[1]
156
- draw.text((x - text_w//2 + dx, y - text_h//2 + dy), txt, fill=(0, 0, 0), font=font)
157
-
158
- # Draw main text
159
- try:
160
- draw.text((x, y), txt, fill=color, font=font, anchor="mm")
161
- except TypeError:
162
- # Fallback for older PIL versions
163
- bbox = draw.textbbox((0, 0), txt, font=font)
164
- text_w = bbox[2] - bbox[0]
165
- text_h = bbox[3] - bbox[1]
166
- draw.text((x - text_w//2, y - text_h//2), txt, fill=color, font=font)
167
-
168
- text_drawn = True
 
 
 
 
169
 
170
- if not text_drawn:
171
- return img, "No text to add (all lines were empty)"
172
-
173
- return image, f"Text added successfully! Font size: {font_size}, Color: {color}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
  # Create the Gradio Interface
176
  with gr.Blocks(title="AI Image Generator & Text Overlay") as demo:
@@ -311,6 +400,17 @@ with gr.Blocks(title="AI Image Generator & Text Overlay") as demo:
311
  outputs=[text_image, status_message]
312
  )
313
 
 
 
 
 
 
 
 
 
 
 
 
314
  # Launch the application
315
  if __name__ == "__main__":
316
  demo.launch(
 
75
  # Text Overlay Functions
76
  def add_text_to_image(img, pattern, line1, line2, line3, font_size, color):
77
  """Overlay 2- or 3-line text on the image in a preset layout."""
78
+ print("=== DEBUG: add_text_to_image called ===")
79
+ print(f"Input image: {type(img)}")
80
+ print(f"Pattern: {pattern}")
81
+ print(f"Lines: [{line1!r}, {line2!r}, {line3!r}]")
82
+ print(f"Font size: {font_size}")
83
+ print(f"Color: {color!r}")
84
+
85
  if img is None:
86
+ print("ERROR: No image provided")
87
  return None, "Please supply an image first."
88
 
89
+ try:
90
+ # Create a working copy
91
+ print(f"Original image mode: {img.mode}, size: {img.size}")
92
+ image = img.convert("RGB")
93
+ print(f"Converted image mode: {image.mode}")
94
+ draw = ImageDraw.Draw(image)
95
+ print("ImageDraw created successfully")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
+ # More robust font loading with better fallbacks
98
+ font = None
99
+ font_paths = [
100
+ "DejaVuSans-Bold.ttf",
101
+ "arial.ttf",
102
+ "/System/Library/Fonts/Arial.ttf",
103
+ "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
104
+ "/usr/share/fonts/TTF/arial.ttf",
105
+ ]
106
+
107
+ print("Attempting to load fonts...")
108
+ for i, font_path in enumerate(font_paths):
109
+ try:
110
+ font = ImageFont.truetype(font_path, font_size)
111
+ print(f"SUCCESS: Loaded font {font_path}")
112
+ break
113
+ except (OSError, IOError) as e:
114
+ print(f"FAILED: Font {font_path} - {e}")
115
+ continue
116
+
117
+ # Final fallback to default font
118
+ if font is None:
119
+ try:
120
+ font = ImageFont.load_default()
121
+ print("Using default font as fallback")
122
+ except Exception as e:
123
+ print(f"ERROR: Even default font failed: {e}")
124
+ return None, f"Font loading error: {e}"
125
 
126
+ w, h = image.size
127
+ print(f"Image dimensions: {w}x{h}")
128
+ positions = []
129
+
130
+ # Define text positioning patterns
131
+ if pattern == "2-lines-top":
132
+ positions = [(w // 2, int(h * 0.10)), (w // 2, int(h * 0.20))]
133
+ elif pattern == "2-lines-bottom":
134
+ positions = [(w // 2, int(h * 0.80)), (w // 2, int(h * 0.90))]
135
+ elif pattern == "2-lines-center":
136
+ positions = [(w // 2, int(h * 0.45)), (w // 2, int(h * 0.55))]
137
+ elif pattern == "3-lines-center":
138
+ positions = [(w // 2, int(h * 0.40)), (w // 2, int(h * 0.50)), (w // 2, int(h * 0.60))]
139
+ elif pattern == "3-lines-top":
140
+ positions = [(w // 2, int(h * 0.10)), (w // 2, int(h * 0.20)), (w // 2, int(h * 0.30))]
141
+ elif pattern == "3-lines-bottom":
142
+ positions = [(w // 2, int(h * 0.70)), (w // 2, int(h * 0.80)), (w // 2, int(h * 0.90))]
143
  else:
144
+ print(f"WARNING: Unknown pattern '{pattern}', using default")
145
+ positions = [(w // 2, int(h * 0.50))]
 
 
 
 
 
 
 
 
146
 
147
+ print(f"Text positions calculated: {positions}")
148
+
149
+ # Convert hex color to RGB tuple if needed
150
+ original_color = color
151
+ if isinstance(color, str) and color.startswith('#'):
152
+ print(f"Converting hex color {color}")
153
+ color = color.lstrip('#')
154
+ if len(color) == 6:
155
+ color = tuple(int(color[i:i+2], 16) for i in (0, 2, 4))
156
+ print(f"Converted to RGB: {color}")
157
+ else:
158
+ print("Invalid hex color, using white")
159
+ color = (255, 255, 255)
160
+ elif isinstance(color, str):
161
+ print(f"Non-hex color string: {color}, using white")
162
+ color = (255, 255, 255)
163
+
164
+ # Draw text with better visibility
165
+ lines = [line1, line2, line3][:len(positions)]
166
+ print(f"Active lines: {lines}")
167
+ text_drawn = False
168
+
169
+ for i, ((x, y), txt) in enumerate(zip(positions, lines)):
170
+ if txt and txt.strip():
171
+ print(f"Drawing line {i+1}: '{txt}' at position ({x}, {y})")
172
+
173
+ # Add text stroke/outline for better visibility
174
+ stroke_width = max(1, font_size // 20)
175
+ print(f"Using stroke width: {stroke_width}")
176
+
177
+ try:
178
+ # Draw text outline (black)
179
+ for dx in [-stroke_width, 0, stroke_width]:
180
+ for dy in [-stroke_width, 0, stroke_width]:
181
+ if dx != 0 or dy != 0:
182
+ try:
183
+ draw.text((x + dx, y + dy), txt, fill=(0, 0, 0), font=font, anchor="mm")
184
+ except TypeError as e:
185
+ print(f"Anchor not supported: {e}, using fallback")
186
+ # Fallback for older PIL versions without anchor
187
+ try:
188
+ bbox = draw.textbbox((0, 0), txt, font=font)
189
+ text_w = bbox[2] - bbox[0]
190
+ text_h = bbox[3] - bbox[1]
191
+ draw.text((x - text_w//2 + dx, y - text_h//2 + dy), txt, fill=(0, 0, 0), font=font)
192
+ except Exception as bbox_e:
193
+ print(f"Textbbox also failed: {bbox_e}, using basic positioning")
194
+ draw.text((x + dx, y + dy), txt, fill=(0, 0, 0), font=font)
195
+
196
+ # Draw main text
197
+ try:
198
+ draw.text((x, y), txt, fill=color, font=font, anchor="mm")
199
+ print(f"Main text drawn with anchor at ({x}, {y})")
200
+ except TypeError as e:
201
+ print(f"Anchor not supported for main text: {e}, using fallback")
202
+ # Fallback for older PIL versions
203
  try:
 
 
 
204
  bbox = draw.textbbox((0, 0), txt, font=font)
205
  text_w = bbox[2] - bbox[0]
206
  text_h = bbox[3] - bbox[1]
207
+ fallback_x = x - text_w//2
208
+ fallback_y = y - text_h//2
209
+ draw.text((fallback_x, fallback_y), txt, fill=color, font=font)
210
+ print(f"Fallback text drawn at ({fallback_x}, {fallback_y})")
211
+ except Exception as bbox_e:
212
+ print(f"Textbbox also failed: {bbox_e}, using basic positioning")
213
+ draw.text((x, y), txt, fill=color, font=font)
214
+
215
+ text_drawn = True
216
+ print(f"Successfully drew line {i+1}")
217
+
218
+ except Exception as e:
219
+ print(f"ERROR drawing text line {i+1}: {e}")
220
+ import traceback
221
+ traceback.print_exc()
222
+ else:
223
+ print(f"Skipping empty line {i+1}")
224
 
225
+ if not text_drawn:
226
+ print("No text was drawn")
227
+ return img, "No text to add (all lines were empty)"
228
+
229
+ print("=== Text drawing completed ===")
230
+ print(f"Returning image with mode: {image.mode}, size: {image.size}")
231
+ return image, f"Text added! Pattern: {pattern}, Font: {font_size}px, Color: {original_color}, Lines drawn: {sum(1 for line in lines if line and line.strip())}"
232
+
233
+ except Exception as e:
234
+ print(f"CRITICAL ERROR in add_text_to_image: {e}")
235
+ import traceback
236
+ traceback.print_exc()
237
+ return None, f"Error adding text: {str(e)}"
238
+
239
+ def test_text_overlay():
240
+ """Test function to verify text overlay works"""
241
+ print("=== Testing basic text overlay ===")
242
+ try:
243
+ # Create a simple test image
244
+ from PIL import Image, ImageDraw, ImageFont
245
+ test_img = Image.new('RGB', (400, 300), color='blue')
246
+ draw = ImageDraw.Draw(test_img)
247
+
248
+ # Try to draw simple text
249
+ try:
250
+ font = ImageFont.load_default()
251
+ draw.text((200, 150), "TEST", fill='white', font=font, anchor="mm")
252
+ print("Basic text drawing works!")
253
+ return test_img, "Test successful"
254
+ except Exception as e:
255
+ print(f"Basic text drawing failed: {e}")
256
+ draw.text((50, 100), "TEST", fill='white')
257
+ print("Fallback text drawing works!")
258
+ return test_img, "Test with fallback"
259
+
260
+ except Exception as e:
261
+ print(f"Test failed completely: {e}")
262
+ return None, f"Test failed: {e}"
263
 
264
  # Create the Gradio Interface
265
  with gr.Blocks(title="AI Image Generator & Text Overlay") as demo:
 
400
  outputs=[text_image, status_message]
401
  )
402
 
403
+ # In the Text Overlay tab, add this button for testing:
404
+ with gr.Row():
405
+ test_btn = gr.Button("🔧 Test Text Overlay", variant="secondary")
406
+
407
+ # Add this event handler:
408
+ test_btn.click(
409
+ test_text_overlay,
410
+ inputs=[],
411
+ outputs=[text_image, status_message]
412
+ )
413
+
414
  # Launch the application
415
  if __name__ == "__main__":
416
  demo.launch(