AkashKumarave commited on
Commit
0a3b563
·
verified ·
1 Parent(s): 3380cf2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +193 -196
app.py CHANGED
@@ -1,197 +1,194 @@
1
- import json
2
- import os
3
- import time
4
- import uuid
5
- import tempfile
6
- from PIL import Image, ImageDraw, ImageFont
7
- import gradio as gr
8
- import base64
9
- import mimetypes
10
- from io import BytesIO
11
-
12
- from google import genai
13
- from google.genai import types
14
-
15
- def generate(text, images, api_key, model="gemini-2.5-flash-image-preview"):
16
- # Initialize client using provided api_key (or fallback to env variable)
17
- client = genai.Client(api_key=(api_key.strip() if api_key and api_key.strip() != ""
18
- else os.environ.get("GEMINI_API_KEY")))
19
-
20
- # Prepare contents with images first, then text
21
- contents = images + [text]
22
-
23
- response = client.models.generate_content(
24
- model=model,
25
- contents=contents,
26
- )
27
-
28
- text_response = ""
29
- image_path = None
30
-
31
- for part in response.candidates[0].content.parts:
32
- if part.text is not None:
33
- text_response += part.text + "\n"
34
- elif part.inline_data is not None:
35
- # Create a temporary file to store the generated image
36
- with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp:
37
- temp_path = tmp.name
38
- generated_image = Image.open(BytesIO(part.inline_data.data))
39
- generated_image.save(temp_path)
40
- image_path = temp_path
41
- print(f"Generated image saved to: {temp_path} with prompt: {text}")
42
-
43
- return image_path, text_response
44
-
45
- def load_uploaded_images(uploaded_files):
46
- """Load and display uploaded images immediately"""
47
- uploaded_images = []
48
- if uploaded_files:
49
- for file in uploaded_files:
50
- if file.name.lower().endswith(('.png', '.jpg', '.jpeg', '.webp')):
51
- img = Image.open(file.name)
52
- if img.mode == "RGBA":
53
- img = img.convert("RGBA")
54
- uploaded_images.append(img)
55
- return uploaded_images
56
-
57
- def process_image_and_prompt(uploaded_files, prompt, gemini_api_key):
58
- try:
59
- input_text = prompt
60
- model = "gemini-2.5-flash-image-preview"
61
-
62
- # Load images from uploaded files
63
- images = []
64
- uploaded_images = []
65
- if uploaded_files:
66
- for file in uploaded_files:
67
- if file.name.lower().endswith(('.png', '.jpg', '.jpeg', '.webp')):
68
- img = Image.open(file.name)
69
- if img.mode == "RGBA":
70
- img = img.convert("RGBA")
71
- images.append(img)
72
- uploaded_images.append(img)
73
-
74
- if not images:
75
- raise gr.Error("Please upload at least one image", duration=5)
76
-
77
- # Format: [dress_image, model_image, text_input] or [image1, image2, ..., text_input]
78
- image_path, text_response = generate(text=input_text, images=images, api_key=gemini_api_key, model=model)
79
-
80
- if image_path:
81
- # Load and convert the image if needed.
82
- result_img = Image.open(image_path)
83
- if result_img.mode == "RGBA":
84
- result_img = result_img.convert("RGBA")
85
- return uploaded_images, [result_img], "" # Return uploaded images, generated image, and empty text output.
86
- else:
87
- # Return uploaded images, no generated image, and the text response.
88
- return uploaded_images, None, text_response
89
- except Exception as e:
90
- raise gr.Error(f"Error Getting {e}", duration=5)
91
-
92
-
93
- # Build a Blocks-based interface with a custom HTML header and CSS
94
- with gr.Blocks(css_paths="style.css",) as demo:
95
- # Custom HTML header with proper class for styling
96
- gr.HTML(
97
- """
98
- <div class="header-container">
99
- <div>
100
- <img src="https://www.gstatic.com/lamda/images/gemini_favicon_f069958c85030456e93de685481c559f160ea06b.png" alt="Gemini logo">
101
- </div>
102
- <div>
103
- <h1>Gemini for Image Editing</h1>
104
- <p>Powered by <a href="https://gradio.app/">Gradio</a>⚡️|
105
- <a href="https://huggingface.co/spaces/ameerazam08/Gemini-Image-Edit?duplicate=true">Duplicate</a> this Repo |
106
- <a href="https://aistudio.google.com/apikey">Get an API Key</a> |
107
- Follow me on Twitter: <a href="https://x.com/Ameerazam18">Ameerazam18</a></p>
108
- </div>
109
- </div>
110
- """
111
- )
112
-
113
- with gr.Accordion("⚠️ API Configuration ⚠️", open=False, elem_classes="config-accordion"):
114
- gr.Markdown("""
115
- - **Issue:** Sometimes the model returns text instead of an image.
116
- ### 🔧 Steps to Address:
117
- 1. **🛠️ Duplicate the Repository**
118
- - Create a separate copy for modifications.
119
- 2. **🔑 Use Your Own Gemini API Key**
120
- - You **must** configure your own Gemini key for generation!
121
- """)
122
-
123
- with gr.Accordion("📌 Usage Instructions", open=False, elem_classes="instructions-accordion"):
124
- gr.Markdown("""
125
- ### 📌 Usage
126
- - Upload an image and enter a prompt to generate outputs.
127
- - If text is returned instead of an image, it will appear in the text output.
128
- - Upload Only PNG Image
129
- - ❌ **Do not use NSFW images!**
130
- """)
131
-
132
- with gr.Row(elem_classes="main-content"):
133
- with gr.Column(elem_classes="input-column"):
134
- image_input = gr.File(
135
- file_types=["image"],
136
- file_count="multiple",
137
- label="Upload Images ",
138
- elem_id="image-input",
139
- elem_classes="upload-box"
140
- )
141
- gemini_api_key = gr.Textbox(
142
- lines=1,
143
- placeholder="Enter Gemini API Key (optional)",
144
- label="Gemini API Key (optional)",
145
- elem_classes="api-key-input"
146
- )
147
- prompt_input = gr.Textbox(
148
- lines=2,
149
- placeholder="Enter prompt here...",
150
- label="Prompt",
151
- elem_classes="prompt-input"
152
- )
153
- submit_btn = gr.Button("Generate", elem_classes="generate-btn")
154
-
155
- with gr.Column(elem_classes="output-column"):
156
- uploaded_gallery = gr.Gallery(label="Uploaded Images", elem_classes="uploaded-gallery")
157
- output_gallery = gr.Gallery(label="Generated Outputs", elem_classes="output-gallery")
158
- output_text = gr.Textbox(
159
- label="Gemini Output",
160
- placeholder="Text response will appear here if no image is generated.",
161
- elem_classes="output-text"
162
- )
163
-
164
- # Set up the interaction with three outputs.
165
- submit_btn.click(
166
- fn=process_image_and_prompt,
167
- inputs=[image_input, prompt_input, gemini_api_key],
168
- outputs=[uploaded_gallery, output_gallery, output_text],
169
- )
170
-
171
- # Update uploaded gallery immediately when files are uploaded
172
- image_input.upload(
173
- fn=load_uploaded_images,
174
- inputs=[image_input],
175
- outputs=[uploaded_gallery],
176
- )
177
-
178
- gr.Markdown("## Try these examples", elem_classes="gr-examples-header")
179
-
180
- examples = [
181
- ["data/1.webp", 'change text to "AMEER"'],
182
- ["data/2.webp", "remove the spoon from hand only"],
183
- ["data/3.webp", 'change text to "Make it "'],
184
- ["data/1.jpg", "add joker style only on face"],
185
- ["data/1777043.jpg", "add joker style only on face"],
186
- ["data/2807615.jpg", "add lipstick on lip only"],
187
- ["data/76860.jpg", "add lipstick on lip only"],
188
- ["data/2807615.jpg", "make it happy looking face only"],
189
- ]
190
-
191
- gr.Examples(
192
- examples=examples,
193
- inputs=[image_input, prompt_input,],
194
- elem_id="examples-grid"
195
- )
196
-
197
  demo.queue(max_size=50).launch(mcp_server=True, share=True)
 
1
+ import json
2
+ import os
3
+ import time
4
+ import uuid
5
+ import tempfile
6
+ from PIL import Image
7
+ import gradio as gr
8
+ import base64
9
+ import mimetypes
10
+ from io import BytesIO
11
+ from google import genai
12
+
13
+ def generate(text, images, api_key=None, model="gemini-2.5-flash-image-preview"):
14
+ # Initialize client using provided api_key or fallback to environment variable
15
+ api_key = api_key.strip() if api_key and api_key.strip() != "" else os.environ.get("GEMINI_API_KEY", "AIzaSyDL5Rilo7ptJpUOZdY6wy8PJYUcVcnDADs")
16
+ client = genai.Client(api_key=api_key)
17
+
18
+ # Prepare contents with images first, then text
19
+ contents = images + [text]
20
+
21
+ response = client.models.generate_content(
22
+ model=model,
23
+ contents=contents,
24
+ )
25
+
26
+ text_response = ""
27
+ image_path = None
28
+
29
+ for part in response.candidates[0].content.parts:
30
+ if part.text is not None:
31
+ text_response += part.text + "\n"
32
+ elif part.inline_data is not None:
33
+ # Create a temporary file to store the generated image
34
+ with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp:
35
+ temp_path = tmp.name
36
+ generated_image = Image.open(BytesIO(part.inline_data.data))
37
+ generated_image.save(temp_path)
38
+ image_path = temp_path
39
+ print(f"Generated image saved to: {temp_path} with prompt: {text}")
40
+
41
+ return image_path, text_response
42
+
43
+ def load_uploaded_images(uploaded_files):
44
+ """Load and display uploaded images immediately"""
45
+ uploaded_images = []
46
+ if uploaded_files:
47
+ for file in uploaded_files:
48
+ if file.name.lower().endswith(('.png', '.jpg', '.jpeg', '.webp')):
49
+ img = Image.open(file.name)
50
+ if img.mode == "RGBA":
51
+ img = img.convert("RGBA")
52
+ uploaded_images.append(img)
53
+ return uploaded_images
54
+
55
+ def process_image_and_prompt(uploaded_files, prompt, gemini_api_key):
56
+ try:
57
+ input_text = prompt
58
+ model = "gemini-2.5-flash-image-preview"
59
+
60
+ # Load images from uploaded files
61
+ images = []
62
+ uploaded_images = []
63
+ if uploaded_files:
64
+ for file in uploaded_files:
65
+ if file.name.lower().endswith(('.png', '.jpg', '.jpeg', '.webp')):
66
+ img = Image.open(file.name)
67
+ if img.mode == "RGBA":
68
+ img = img.convert("RGBA")
69
+ images.append(img)
70
+ uploaded_images.append(img)
71
+
72
+ if not images:
73
+ raise gr.Error("Please upload at least one image", duration=5)
74
+
75
+ # Call generate with images and prompt
76
+ image_path, text_response = generate(text=input_text, images=images, api_key=gemini_api_key, model=model)
77
+
78
+ if image_path:
79
+ # Load and convert the generated image if needed
80
+ result_img = Image.open(image_path)
81
+ if result_img.mode == "RGBA":
82
+ result_img = result_img.convert("RGBA")
83
+ return uploaded_images, [result_img], "" # Return uploaded images, generated image, and empty text output
84
+ else:
85
+ # Return uploaded images, no generated image, and the text response
86
+ return uploaded_images, None, text_response
87
+ except Exception as e:
88
+ raise gr.Error(f"Error: {e}", duration=5)
89
+
90
+ # Build a Blocks-based interface with a custom HTML header and CSS
91
+ with gr.Blocks(css="style.css") as demo:
92
+ # Custom HTML header with proper class for styling
93
+ gr.HTML(
94
+ """
95
+ <div class="header-container">
96
+ <div>
97
+ <img src="https://www.gstatic.com/lamda/images/gemini_favicon_f069958c85030456e93de685481c559f160ea06b.png" alt="Gemini logo">
98
+ </div>
99
+ <div>
100
+ <h1>Gemini for Image Editing</h1>
101
+ <p>Powered by <a href="https://gradio.app/">Gradio</a> |
102
+ <a href="https://huggingface.co/spaces/ameerazam08/Gemini-Image-Edit?duplicate=true">Duplicate</a> this Repo |
103
+ <a href="https://aistudio.google.com/apikey">Get an API Key</a> |
104
+ Follow me on Twitter: <a href="https://x.com/Ameerazam18">Ameerazam18</a></p>
105
+ </div>
106
+ </div>
107
+ """
108
+ )
109
+
110
+ with gr.Accordion("API Configuration", open=False, elem_classes="config-accordion"):
111
+ gr.Markdown("""
112
+ - **Issue:** Sometimes the model returns text instead of an image.
113
+ ### Steps to Address:
114
+ 1. **Duplicate the Repository**
115
+ - Create a separate copy for modifications.
116
+ 2. **Use Your Own Gemini API Key**
117
+ - You **must** configure your own Gemini key for generation!
118
+ """)
119
+
120
+ with gr.Accordion("Usage Instructions", open=False, elem_classes="instructions-accordion"):
121
+ gr.Markdown("""
122
+ ### Usage
123
+ - Upload an image and enter a prompt to generate outputs.
124
+ - If text is returned instead of an image, it will appear in the text output.
125
+ - Upload only PNG, JPG, JPEG, or WEBP images.
126
+ - **Do not use NSFW images!**
127
+ """)
128
+
129
+ with gr.Row(elem_classes="main-content"):
130
+ with gr.Column(elem_classes="input-column"):
131
+ image_input = gr.File(
132
+ file_types=["image"],
133
+ file_count="multiple",
134
+ label="Upload Images",
135
+ elem_id="image-input",
136
+ elem_classes="upload-box"
137
+ )
138
+ gemini_api_key = gr.Textbox(
139
+ lines=1,
140
+ placeholder="Enter Gemini API Key (optional)",
141
+ label="Gemini API Key (optional)",
142
+ elem_classes="api-key-input"
143
+ )
144
+ prompt_input = gr.Textbox(
145
+ lines=2,
146
+ placeholder="Enter prompt here...",
147
+ label="Prompt",
148
+ elem_classes="prompt-input"
149
+ )
150
+ submit_btn = gr.Button("Generate", elem_classes="generate-btn")
151
+
152
+ with gr.Column(elem_classes="output-column"):
153
+ uploaded_gallery = gr.Gallery(label="Uploaded Images", elem_classes="uploaded-gallery")
154
+ output_gallery = gr.Gallery(label="Generated Outputs", elem_classes="output-gallery")
155
+ output_text = gr.Textbox(
156
+ label="Gemini Output",
157
+ placeholder="Text response will appear here if no image is generated.",
158
+ elem_classes="output-text"
159
+ )
160
+
161
+ # Set up the interaction with three outputs
162
+ submit_btn.click(
163
+ fn=process_image_and_prompt,
164
+ inputs=[image_input, prompt_input, gemini_api_key],
165
+ outputs=[uploaded_gallery, output_gallery, output_text],
166
+ )
167
+
168
+ # Update uploaded gallery immediately when files are uploaded
169
+ image_input.upload(
170
+ fn=load_uploaded_images,
171
+ inputs=[image_input],
172
+ outputs=[uploaded_gallery],
173
+ )
174
+
175
+ gr.Markdown("## Try these examples", elem_classes="gr-examples-header")
176
+
177
+ examples = [
178
+ ["data/1.webp", 'change text to "AMEER"'],
179
+ ["data/2.webp", "remove the spoon from hand only"],
180
+ ["data/3.webp", 'change text to "Make it "'],
181
+ ["data/1.jpg", "add joker style only on face"],
182
+ ["data/1777043.jpg", "add joker style only on face"],
183
+ ["data/2807615.jpg", "add lipstick on lip only"],
184
+ ["data/76860.jpg", "add lipstick on lip only"],
185
+ ["data/2807615.jpg", "make it happy looking face only"],
186
+ ]
187
+
188
+ gr.Examples(
189
+ examples=examples,
190
+ inputs=[image_input, prompt_input],
191
+ elem_id="examples-grid"
192
+ )
193
+
 
 
 
194
  demo.queue(max_size=50).launch(mcp_server=True, share=True)