Deadmon commited on
Commit
1b6c50f
·
verified ·
1 Parent(s): 4c18034

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +117 -41
app.py CHANGED
@@ -8,37 +8,65 @@ import io
8
  from PIL import Image
9
 
10
  def save_binary_file(file_name, data):
11
- with open(file_name, "wb") as f:
12
- f.write(data)
 
13
 
14
  def generate_image(prompt, image=None, output_filename="generated_image"):
15
- client = genai.Client(api_key="AIzaSyAQcy3LfrkMy6DqS_8MqftAXu1Bx_ov_E8")
 
 
 
 
16
  model = "gemini-2.0-flash-exp-image-generation"
17
  parts = [types.Part.from_text(text=prompt)]
18
-
 
19
  if image:
 
20
  img_byte_arr = io.BytesIO()
21
  image.save(img_byte_arr, format="PNG")
22
  img_bytes = img_byte_arr.getvalue()
 
23
  parts.append({
24
  "inline_data": {
25
  "mime_type": "image/png",
26
  "data": img_bytes
27
  }
28
  })
29
-
30
- contents = [types.Content(role="user", parts=parts)]
 
 
 
 
 
31
  generate_content_config = types.GenerateContentConfig(
32
  temperature=1,
33
  top_p=0.95,
34
  top_k=40,
35
  max_output_tokens=8192,
36
- response_modalities=["image", "text"],
37
- response_mime_type="text/plain"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  )
39
-
40
- response = client.models.generate_content_stream(model=model, contents=contents, config=generate_content_config)
41
-
42
  for chunk in response:
43
  if not chunk.candidates or not chunk.candidates[0].content or not chunk.candidates[0].content.parts:
44
  continue
@@ -47,62 +75,110 @@ def generate_image(prompt, image=None, output_filename="generated_image"):
47
  file_extension = mimetypes.guess_extension(inline_data.mime_type)
48
  filename = f"{output_filename}{file_extension}"
49
  save_binary_file(filename, inline_data.data)
50
-
 
51
  img = Image.open(io.BytesIO(inline_data.data))
52
  return img, f"Image saved as {filename}"
53
  else:
54
  return None, chunk.text
55
-
56
  return None, "No image generated"
57
 
58
- def chat_handler(prompt, user_image, chat_history, gallery, output_filename="generated_image"):
 
 
 
59
  if prompt:
60
- chat_history.append(("User", prompt))
61
-
 
 
 
 
 
62
  if not prompt and not user_image:
63
- chat_history.append(("Assistant", "Please provide a prompt or an image."))
64
- return chat_history, user_image, None, gallery, ""
65
-
 
66
  img, status = generate_image(prompt or "Generate an image", user_image, output_filename)
67
-
68
- chat_history.append(("Assistant", status))
 
 
69
  if img:
70
- gallery.append(img)
71
-
72
- return chat_history, user_image, img, gallery, ""
 
 
 
 
 
 
 
 
 
 
 
73
 
 
 
 
74
  with gr.Blocks(title="Image Editing Chatbot") as demo:
75
  gr.Markdown("# Image Editing Chatbot")
76
  gr.Markdown("Upload an image and/or type a prompt to generate or edit an image using Google's Gemini model")
77
-
78
- chatbot = gr.Chatbot(label="Chat", height=300)
79
- gallery_output = gr.Gallery(label="Generated Images", show_label=True, height=200)
80
-
 
 
 
 
 
 
81
  with gr.Row():
82
  uploaded_image_output = gr.Image(label="Uploaded Image")
83
  generated_image_output = gr.Image(label="Generated Image")
84
-
 
85
  with gr.Row():
86
  with gr.Column():
87
- image_input = gr.Image(label="Upload Image", type="pil", height=100)
88
- prompt_input = gr.Textbox(label="Prompt", placeholder="Enter your image description here...", lines=3)
89
- filename_input = gr.Textbox(label="Output Filename", value="generated_image", placeholder="Enter desired filename")
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  generate_btn = gr.Button("Generate Image")
91
-
 
92
  chat_state = gr.State([])
93
- gallery_state = gr.State([])
94
-
95
  generate_btn.click(
96
  fn=chat_handler,
97
- inputs=[prompt_input, image_input, chat_state, gallery_state, filename_input],
98
- outputs=[chatbot, uploaded_image_output, generated_image_output, gallery_output, prompt_input]
99
  )
100
-
 
101
  prompt_input.submit(
102
  fn=chat_handler,
103
- inputs=[prompt_input, image_input, chat_state, gallery_state, filename_input],
104
- outputs=[chatbot, uploaded_image_output, generated_image_output, gallery_output, prompt_input]
105
  )
106
 
107
  if __name__ == "__main__":
108
- demo.launch()
 
8
  from PIL import Image
9
 
10
  def save_binary_file(file_name, data):
11
+ f = open(file_name, "wb")
12
+ f.write(data)
13
+ f.close()
14
 
15
  def generate_image(prompt, image=None, output_filename="generated_image"):
16
+ # Initialize client with the API key
17
+ client = genai.Client(
18
+ api_key="AIzaSyAQcy3LfrkMy6DqS_8MqftAXu1Bx_ov_E8",
19
+ )
20
+
21
  model = "gemini-2.0-flash-exp-image-generation"
22
  parts = [types.Part.from_text(text=prompt)]
23
+
24
+ # If an image is provided, add it to the content
25
  if image:
26
+ # Convert PIL Image to bytes
27
  img_byte_arr = io.BytesIO()
28
  image.save(img_byte_arr, format="PNG")
29
  img_bytes = img_byte_arr.getvalue()
30
+ # Add the image as a Part with inline_data
31
  parts.append({
32
  "inline_data": {
33
  "mime_type": "image/png",
34
  "data": img_bytes
35
  }
36
  })
37
+
38
+ contents = [
39
+ types.Content(
40
+ role="user",
41
+ parts=parts,
42
+ ),
43
+ ]
44
  generate_content_config = types.GenerateContentConfig(
45
  temperature=1,
46
  top_p=0.95,
47
  top_k=40,
48
  max_output_tokens=8192,
49
+ response_modalities=[
50
+ "image",
51
+ "text",
52
+ ],
53
+ safety_settings=[
54
+ types.SafetySetting(
55
+ category="HARM_CATEGORY_CIVIC_INTEGRITY",
56
+ threshold="OFF",
57
+ ),
58
+ ],
59
+ response_mime_type="text/plain",
60
+ )
61
+
62
+ # Generate the content
63
+ response = client.models.generate_content_stream(
64
+ model=model,
65
+ contents=contents,
66
+ config=generate_content_config,
67
  )
68
+
69
+ # Process the response
 
70
  for chunk in response:
71
  if not chunk.candidates or not chunk.candidates[0].content or not chunk.candidates[0].content.parts:
72
  continue
 
75
  file_extension = mimetypes.guess_extension(inline_data.mime_type)
76
  filename = f"{output_filename}{file_extension}"
77
  save_binary_file(filename, inline_data.data)
78
+
79
+ # Convert binary data to PIL Image
80
  img = Image.open(io.BytesIO(inline_data.data))
81
  return img, f"Image saved as {filename}"
82
  else:
83
  return None, chunk.text
84
+
85
  return None, "No image generated"
86
 
87
+ # Function to handle chat interaction
88
+ def chat_handler(prompt, user_image, chat_history, output_filename="generated_image"):
89
+ # Add the user prompt and image to the chat history
90
+ user_message_content = []
91
  if prompt:
92
+ user_message_content.append(prompt)
93
+ if user_image:
94
+ user_message_content.append(user_image) # Keep PIL Image in history for display
95
+ if user_message_content:
96
+ chat_history.append({"role": "user", "content": user_message_content if len(user_message_content) > 1 else user_message_content[0]})
97
+
98
+ # If no input, return early
99
  if not prompt and not user_image:
100
+ chat_history.append({"role": "assistant", "content": "Please provide a prompt or an image."})
101
+ return chat_history, user_image, None, ""
102
+
103
+ # Generate image based on user input
104
  img, status = generate_image(prompt or "Generate an image", user_image, output_filename)
105
+
106
+ assistant_message_content = []
107
+ assistant_message_content.append(status) # Add text status
108
+
109
  if img:
110
+ # Create thumbnail for chatbot
111
+ thumbnail_size = (100, 100) # Define thumbnail size
112
+ thumbnail = img.copy()
113
+ thumbnail.thumbnail(thumbnail_size)
114
+
115
+ # Convert thumbnail to base64 for chatbot display
116
+ buffered = io.BytesIO()
117
+ thumbnail.save(buffered, format="PNG")
118
+ thumbnail_base64 = base64.b64encode(buffered.getvalue()).decode()
119
+ thumbnail_data_uri = f"data:image/png;base64,{thumbnail_base64}"
120
+ assistant_message_content.append(thumbnail_data_uri) # Add thumbnail to message
121
+
122
+ # Add assistant's response to chat history
123
+ chat_history.append({"role": "assistant", "content": assistant_message_content if len(assistant_message_content) > 1 else assistant_message_content[0]})
124
 
125
+ return chat_history, user_image, img, ""
126
+
127
+ # Create Gradio interface
128
  with gr.Blocks(title="Image Editing Chatbot") as demo:
129
  gr.Markdown("# Image Editing Chatbot")
130
  gr.Markdown("Upload an image and/or type a prompt to generate or edit an image using Google's Gemini model")
131
+
132
+ # Chatbot display area for text messages
133
+ chatbot = gr.Chatbot(
134
+ label="Chat",
135
+ height=300,
136
+ type="messages",
137
+ avatar_images=(None, None)
138
+ )
139
+
140
+ # Separate image outputs
141
  with gr.Row():
142
  uploaded_image_output = gr.Image(label="Uploaded Image")
143
  generated_image_output = gr.Image(label="Generated Image")
144
+
145
+ # Input area
146
  with gr.Row():
147
  with gr.Column():
148
+ image_input = gr.Image(
149
+ label="Upload Image",
150
+ type="pil",
151
+ scale=1,
152
+ height=100
153
+ )
154
+ prompt_input = gr.Textbox(
155
+ label="Prompt",
156
+ placeholder="Enter your image description here...",
157
+ lines=3
158
+ )
159
+ filename_input = gr.Textbox(
160
+ label="Output Filename",
161
+ value="generated_image",
162
+ placeholder="Enter desired filename (without extension)"
163
+ )
164
  generate_btn = gr.Button("Generate Image")
165
+
166
+ # State to maintain chat history
167
  chat_state = gr.State([])
168
+
169
+ # Connect the button to the chat handler
170
  generate_btn.click(
171
  fn=chat_handler,
172
+ inputs=[prompt_input, image_input, chat_state, filename_input],
173
+ outputs=[chatbot, uploaded_image_output, generated_image_output, prompt_input]
174
  )
175
+
176
+ # Also allow Enter key to submit
177
  prompt_input.submit(
178
  fn=chat_handler,
179
+ inputs=[prompt_input, image_input, chat_state, filename_input],
180
+ outputs=[chatbot, uploaded_image_output, generated_image_output, prompt_input]
181
  )
182
 
183
  if __name__ == "__main__":
184
+ demo.launch()