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

Update app.py - changes to the UI

Browse files
Files changed (1) hide show
  1. app.py +73 -33
app.py CHANGED
@@ -78,59 +78,99 @@ def add_text_to_image(img, pattern, line1, line2, line3, font_size, color):
78
  if img is None:
79
  return None, "Please supply an image first."
80
 
81
- # Ensure editable copy
82
- original_mode = img.mode
83
- image = img.convert("RGBA")
84
  draw = ImageDraw.Draw(image)
85
 
86
- # Pick a font (robust fallback for different platforms)
87
- try:
88
- font = ImageFont.truetype("DejaVuSans-Bold.ttf", font_size)
89
- except (OSError, IOError):
 
 
 
 
 
 
 
90
  try:
91
- # Try common system fonts
92
- font = ImageFont.truetype("arial.ttf", font_size) # Windows
93
  except (OSError, IOError):
94
- try:
95
- font = ImageFont.truetype("/System/Library/Fonts/Arial.ttf", font_size) # macOS
96
- except (OSError, IOError):
97
- try:
98
- font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", font_size) # Linux
99
- except (OSError, IOError):
100
- font = ImageFont.load_default()
 
 
101
 
102
  w, h = image.size
103
  positions = []
104
 
105
  # Define text positioning patterns
106
  if pattern == "2-lines-top":
107
- positions = [(w / 2, h * 0.10), (w / 2, h * 0.20)]
108
  elif pattern == "2-lines-bottom":
109
- positions = [(w / 2, h * 0.80), (w / 2, h * 0.90)]
110
  elif pattern == "2-lines-center":
111
- positions = [(w / 2, h * 0.45), (w / 2, h * 0.55)]
112
  elif pattern == "3-lines-center":
113
- positions = [(w / 2, h * 0.40), (w / 2, h * 0.50), (w / 2, h * 0.60)]
114
  elif pattern == "3-lines-top":
115
- positions = [(w / 2, h * 0.10), (w / 2, h * 0.20), (w / 2, h * 0.30)]
116
  elif pattern == "3-lines-bottom":
117
- positions = [(w / 2, h * 0.70), (w / 2, h * 0.80), (w / 2, h * 0.90)]
118
 
119
- # Ensure color is in the right format
120
  if isinstance(color, str) and color.startswith('#'):
121
- color = color # PIL handles hex colors fine
122
-
123
- # Draw text lines
 
 
 
 
 
124
  lines = [line1, line2, line3][:len(positions)]
 
 
125
  for (x, y), txt in zip(positions, lines):
126
- if txt and txt.strip(): # Only draw non-empty text
127
- draw.text((x, y), txt, fill=color, font=font, anchor="mm")
128
-
129
- # Convert back to original mode if needed
130
- if original_mode != "RGBA":
131
- image = image.convert(original_mode)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
 
133
- return image, "Text added successfully!"
 
 
 
134
 
135
  # Create the Gradio Interface
136
  with gr.Blocks(title="AI Image Generator & Text Overlay") as demo:
 
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: