feat: working image template in Safari on IOS and Chrome in Android" [fragrantica ad71397] feat: working image template in Safari on IOS and Chrome in Android

#7
by ibombonato - opened
Files changed (1) hide show
  1. app.py +61 -43
app.py CHANGED
@@ -144,33 +144,54 @@ def clean_env_vars():
144
  os.environ.pop("OPENAI_MODEL_NAME", None)
145
 
146
  js_share_logic = """
147
- async (image_data_url) => {
148
- if (!image_data_url) {
149
- console.error("Share button clicked, but no image data URL found.");
150
  alert("No image to share. Please generate an image first.");
151
  return;
152
  }
153
 
154
- const dataUrl = image_data_url;
155
-
156
  try {
157
- const response = await fetch(dataUrl);
158
  const blob = await response.blob();
159
- const file = new File([blob], "shared_image.png", { type: "image/png" });
160
-
161
- if (navigator.share && navigator.canShare({ files: [file] })) {
162
- await navigator.share({
163
- files: [file],
164
- title: "Check out this image!",
165
- text: "Created with a cool Gradio app.",
166
- });
167
- } else {
168
- alert("Sharing not supported on this browser.");
169
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  } catch (error) {
171
  if (error.name === 'AbortError') {
172
  console.log("Share dialog cancelled by user.");
173
- // Do nothing, as this is a user-initiated cancellation
174
  } else {
175
  console.error("Error sharing:", error);
176
  alert("An error occurred while trying to share.");
@@ -235,12 +256,8 @@ with gr.Blocks() as demo:
235
  image_coupon_code_input = gr.Textbox(label="Coupon Code", placeholder="Enter coupon code...")
236
  gen_image_btn = gr.Button("Generate Image")
237
  with gr.Column():
238
- image_output = gr.Image(label="Generated Image", height=500, type="pil", interactive=False)
239
- image_data_url_storage = gr.Textbox(
240
- label="Image Data URL (for debugging)",
241
- visible=True,
242
- elem_id="image_data_url_storage"
243
- )
244
  share_button = gr.Button("🚀 Share Image", interactive=False)
245
 
246
  with gr.Tab("Settings"):
@@ -271,24 +288,14 @@ with gr.Blocks() as demo:
271
  return
272
  yield report.raw
273
 
274
- def image_to_base64(pil_image):
275
- print(f"image_to_base64 called. pil_image type: {type(pil_image)}")
276
- if pil_image is None:
277
- print("pil_image is None. Returning empty string and interactive=False.")
278
- return "", gr.update(interactive=False)
279
- buffered = BytesIO()
280
- pil_image.save(buffered, format="PNG")
281
- img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
282
- data_url = f"data:image/png;base64,{img_str}"
283
- print("Returning data_url and interactive=True.")
284
- return data_url, gr.update(interactive=True)
285
 
286
  def generate_image(product_image_url, product_name, original_price, final_price, coupon_code):
287
  tool = GenerateImageTool()
288
  original_price_str = f"{original_price:.2f}".replace('.', ',')
289
  final_price_str = f"{final_price:.2f}".replace('.', ',')
290
 
291
- yield gr.update(interactive=False, value="Generating..."), None
292
 
293
  image_path = tool._run(
294
  product_image_url=product_image_url,
@@ -298,17 +305,28 @@ with gr.Blocks() as demo:
298
  coupon_code=coupon_code
299
  )
300
 
301
- pil_image = Image.open(image_path)
302
- yield gr.update(interactive=True, value="Generate Image"), pil_image
 
 
 
 
 
 
 
 
 
 
 
303
 
304
  generate_ad_button.click(generate_ad, inputs=[url_input, store_name_input, main_cupom_input, main_cupom_discount_percentage_input, cupom_1_input, original_price_input, discounted_price_input, openai_key_input, natura_token_input, openai_base_url_input, openai_model_name_input], outputs=[generate_ad_button, ad_output])
305
  clear_button.click(clear_fields, inputs=[], outputs=[url_input, original_price_input, discounted_price_input])
306
  analyze_fragrantica_button.click(analyze_fragrantica_url, inputs=[fragrantica_url_input, openai_key_input, natura_token_input, openai_base_url_input, openai_model_name_input], outputs=fragrantica_output)
307
- gen_image_btn.click(generate_image,
308
- inputs=[image_product_url_input, image_product_name_input, image_original_price_input, image_final_price_input, image_coupon_code_input],
309
- outputs=[gen_image_btn, image_output])
310
- image_output.change(image_to_base64, inputs=image_output, outputs=[image_data_url_storage, share_button])
311
- share_button.click(fn=None, inputs=[image_data_url_storage], js=js_share_logic)
312
 
313
  if __name__ == "__main__":
314
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
144
  os.environ.pop("OPENAI_MODEL_NAME", None)
145
 
146
  js_share_logic = """
147
+ async (image_url) => {
148
+ if (!image_url) {
149
+ console.error("Share button clicked, but no image URL found.");
150
  alert("No image to share. Please generate an image first.");
151
  return;
152
  }
153
 
 
 
154
  try {
155
+ const response = await fetch(image_url);
156
  const blob = await response.blob();
157
+
158
+ const reader = new FileReader();
159
+ reader.readAsDataURL(blob);
160
+ reader.onloadend = async function() {
161
+ const base64data = reader.result;
162
+
163
+ const parts = base64data.split(';base64,');
164
+ const contentType = parts[0].split(':')[1];
165
+ const raw = window.atob(parts[1]);
166
+ const rawLength = raw.length;
167
+ const uInt8Array = new Uint8Array(rawLength);
168
+
169
+ for (let i = 0; i < rawLength; ++i) {
170
+ uInt8Array[i] = raw.charCodeAt(i);
171
+ }
172
+
173
+ const newBlob = new Blob([uInt8Array], { type: contentType });
174
+ const fileName = `shared_image_${new Date().getTime()}.png`;
175
+ const file = new File([newBlob], fileName, { type: contentType });
176
+
177
+ if (navigator.share && navigator.canShare({ files: [file] })) {
178
+ await navigator.share({
179
+ files: [file],
180
+ title: "Image",
181
+ text: "Shared from app.",
182
+ });
183
+ } else {
184
+ alert("Sharing not supported on this browser.");
185
+ }
186
+ };
187
+ reader.onerror = function(error) {
188
+ console.error("Error converting blob to data URL:", error);
189
+ alert("An error occurred while preparing image for sharing.");
190
+ };
191
+
192
  } catch (error) {
193
  if (error.name === 'AbortError') {
194
  console.log("Share dialog cancelled by user.");
 
195
  } else {
196
  console.error("Error sharing:", error);
197
  alert("An error occurred while trying to share.");
 
256
  image_coupon_code_input = gr.Textbox(label="Coupon Code", placeholder="Enter coupon code...")
257
  gen_image_btn = gr.Button("Generate Image")
258
  with gr.Column():
259
+ image_output = gr.Image(label="Generated Image", height=500, type="filepath", interactive=False)
260
+ base64_debug_output = gr.Textbox(label="Base64 Debug Output", visible=True, interactive=False)
 
 
 
 
261
  share_button = gr.Button("🚀 Share Image", interactive=False)
262
 
263
  with gr.Tab("Settings"):
 
288
  return
289
  yield report.raw
290
 
291
+
 
 
 
 
 
 
 
 
 
 
292
 
293
  def generate_image(product_image_url, product_name, original_price, final_price, coupon_code):
294
  tool = GenerateImageTool()
295
  original_price_str = f"{original_price:.2f}".replace('.', ',')
296
  final_price_str = f"{final_price:.2f}".replace('.', ',')
297
 
298
+ yield gr.update(interactive=False, value="Generating..."), None, gr.update(interactive=False)
299
 
300
  image_path = tool._run(
301
  product_image_url=product_image_url,
 
305
  coupon_code=coupon_code
306
  )
307
 
308
+ yield gr.update(interactive=True, value="Generate Image"), image_path, gr.update(interactive=True)
309
+
310
+ def process_image_for_sharing(image_path):
311
+ if image_path is None:
312
+ return ""
313
+ try:
314
+ with open(image_path, "rb") as image_file:
315
+ encoded_string = base64.b64encode(image_file.read()).decode("utf-8")
316
+ data_url = f"data:image/png;base64,{encoded_string}"
317
+ return data_url
318
+ except Exception as e:
319
+ print(f"Error processing image for sharing: {e}")
320
+ return ""
321
 
322
  generate_ad_button.click(generate_ad, inputs=[url_input, store_name_input, main_cupom_input, main_cupom_discount_percentage_input, cupom_1_input, original_price_input, discounted_price_input, openai_key_input, natura_token_input, openai_base_url_input, openai_model_name_input], outputs=[generate_ad_button, ad_output])
323
  clear_button.click(clear_fields, inputs=[], outputs=[url_input, original_price_input, discounted_price_input])
324
  analyze_fragrantica_button.click(analyze_fragrantica_url, inputs=[fragrantica_url_input, openai_key_input, natura_token_input, openai_base_url_input, openai_model_name_input], outputs=fragrantica_output)
325
+ gen_image_btn.click(generate_image,
326
+ inputs=[image_product_url_input, image_product_name_input, image_original_price_input, image_final_price_input, image_coupon_code_input],
327
+ outputs=[gen_image_btn, image_output, share_button])
328
+ share_button.click(fn=process_image_for_sharing, inputs=[image_output], outputs=[base64_debug_output])
329
+ base64_debug_output.change(fn=None, inputs=[base64_debug_output], js=js_share_logic)
330
 
331
  if __name__ == "__main__":
332
  demo.launch(server_name="0.0.0.0", server_port=7860)