bakyt92 commited on
Commit
978622c
·
1 Parent(s): 18839b3

Update app.py - add PIllow

Browse files
Files changed (1) hide show
  1. app.py +113 -50
app.py CHANGED
@@ -1,9 +1,8 @@
1
  import gradio as gr
2
  import requests
3
- from PIL import Image
4
  import io
5
  import openai
6
- from gradio_image_annotation import image_annotator
7
 
8
  # Image Generation Functions
9
  def generate_ideogram_image(api_key, prompt, aspect_ratio="ASPECT_1_1"):
@@ -73,21 +72,70 @@ def process_uploaded_image(image):
73
  return None, "No image uploaded"
74
  return image, "Image uploaded successfully!"
75
 
76
- # Image Annotation Functions
77
- def get_annotations_json(annotations):
78
- """Extract annotations as JSON"""
79
- return annotations.get("boxes", [])
 
80
 
81
- def save_annotated_image(annotations):
82
- """Return the annotated image"""
83
- if annotations and annotations.get("image") is not None:
84
- return annotations["image"]
85
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
  # Create the Gradio Interface
88
- with gr.Blocks(title="AI Image Generator & Annotator MCP Server") as demo:
89
- gr.Markdown("# 🎨 AI Image Generator & Annotator")
90
- gr.Markdown("Generate images with AI or upload your own, then add annotations!")
91
 
92
  # Tab 1: Image Generation
93
  with gr.Tab("🖼️ Image Generation", id="generation_tab"):
@@ -161,56 +209,71 @@ with gr.Blocks(title="AI Image Generator & Annotator MCP Server") as demo:
161
  outputs=[generated_image, status_message]
162
  )
163
 
164
- # Tab 2: Image Annotation
165
- with gr.Tab("📝 Image Annotation", id="annotation_tab"):
166
- gr.Markdown("## Add Signs and Annotations to Images")
167
- gr.Markdown("Upload an image or use one from the generation tab, then add bounding boxes and labels.")
168
 
169
  with gr.Row():
170
  with gr.Column():
171
- # Image annotation component
172
- annotator = image_annotator(
173
- label="Image Annotator",
174
- label_list=["Person", "Object", "Vehicle", "Animal", "Building", "Sign", "Text", "Custom"],
175
- label_colors=[
176
- (255, 0, 0), # Red for Person
177
- (0, 255, 0), # Green for Object
178
- (0, 0, 255), # Blue for Vehicle
179
- (255, 255, 0), # Yellow for Animal
180
- (255, 0, 255), # Magenta for Building
181
- (0, 255, 255), # Cyan for Sign
182
- (128, 0, 128), # Purple for Text
183
- (255, 165, 0) # Orange for Custom
184
  ],
185
- image_type="pil"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  )
187
 
 
188
  with gr.Row():
189
- get_annotations_btn = gr.Button("📊 Get Annotations", variant="secondary")
190
- save_image_btn = gr.Button("💾 Save Annotated Image", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
191
 
192
  with gr.Column():
193
- # Outputs
194
- annotated_output = gr.Image(label="Annotated Image")
195
- annotations_json = gr.JSON(label="Annotations Data")
196
-
197
- # Event handlers for Tab 2
198
- get_annotations_btn.click(
199
- get_annotations_json,
200
- inputs=[annotator],
201
- outputs=[annotations_json]
202
- )
203
 
204
- save_image_btn.click(
205
- save_annotated_image,
206
- inputs=[annotator],
207
- outputs=[annotated_output]
 
208
  )
209
 
210
- # Launch as MCP Server
211
  if __name__ == "__main__":
212
  demo.launch(
213
- share=True, # Create public link for testing
214
  server_name="0.0.0.0",
215
  server_port=7860
216
  )
 
1
  import gradio as gr
2
  import requests
3
+ from PIL import Image, ImageDraw, ImageFont
4
  import io
5
  import openai
 
6
 
7
  # Image Generation Functions
8
  def generate_ideogram_image(api_key, prompt, aspect_ratio="ASPECT_1_1"):
 
72
  return None, "No image uploaded"
73
  return image, "Image uploaded successfully!"
74
 
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
+ # 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:
137
+ gr.Markdown("# 🎨 AI Image Generator & Text Overlay")
138
+ gr.Markdown("Generate images with AI or upload your own, then add custom text overlays!")
139
 
140
  # Tab 1: Image Generation
141
  with gr.Tab("🖼️ Image Generation", id="generation_tab"):
 
209
  outputs=[generated_image, status_message]
210
  )
211
 
212
+ # Tab 2: Add Text Overlay
213
+ with gr.Tab("📝 Add Text", id="text_tab"):
214
+ gr.Markdown("## Overlay Text on Images")
215
+ gr.Markdown("Choose a layout pattern, type your text, and render it on the current image.")
216
 
217
  with gr.Row():
218
  with gr.Column():
219
+ # Text pattern selection
220
+ pattern = gr.Dropdown(
221
+ choices=[
222
+ ("2-lines-top", "2 lines - Top"),
223
+ ("2-lines-center", "2 lines - Center"),
224
+ ("2-lines-bottom", "2 lines - Bottom"),
225
+ ("3-lines-top", "3 lines - Top"),
226
+ ("3-lines-center", "3 lines - Center"),
227
+ ("3-lines-bottom", "3 lines - Bottom")
 
 
 
 
228
  ],
229
+ value="2-lines-top",
230
+ label="Layout Pattern"
231
+ )
232
+
233
+ # Text input fields
234
+ line1_inp = gr.Textbox(
235
+ label="Line 1",
236
+ placeholder="Enter first line of text..."
237
+ )
238
+ line2_inp = gr.Textbox(
239
+ label="Line 2",
240
+ placeholder="Enter second line of text..."
241
+ )
242
+ line3_inp = gr.Textbox(
243
+ label="Line 3",
244
+ placeholder="Enter third line of text..."
245
  )
246
 
247
+ # Styling options
248
  with gr.Row():
249
+ font_size = gr.Slider(
250
+ minimum=12,
251
+ maximum=120,
252
+ value=48,
253
+ step=2,
254
+ label="Font Size"
255
+ )
256
+ color = gr.ColorPicker(
257
+ label="Text Color",
258
+ value="#FFFFFF"
259
+ )
260
+
261
+ add_text_btn = gr.Button("✨ Add Text to Image", variant="primary")
262
 
263
  with gr.Column():
264
+ # Output
265
+ text_image = gr.Image(label="Image with Text Overlay")
 
 
 
 
 
 
 
 
266
 
267
+ # Event handler for Tab 2
268
+ add_text_btn.click(
269
+ add_text_to_image,
270
+ inputs=[generated_image, pattern, line1_inp, line2_inp, line3_inp, font_size, color],
271
+ outputs=[text_image, status_message]
272
  )
273
 
274
+ # Launch the application
275
  if __name__ == "__main__":
276
  demo.launch(
 
277
  server_name="0.0.0.0",
278
  server_port=7860
279
  )