aiqtech commited on
Commit
18aee2c
ยท
verified ยท
1 Parent(s): 7ab58cc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -34
app.py CHANGED
@@ -46,7 +46,7 @@ def image_to_data_uri(image_path: str) -> str:
46
  def run_single_image_logic(prompt: str, image_path: Optional[str] = None, progress=gr.Progress()) -> str:
47
  """Handles text-to-image or single image-to-image using Replicate's Nano Banana."""
48
  try:
49
- progress(0.2, desc="๐ŸŽจ ์ค€๋น„ ์ค‘...")
50
 
51
  # Prepare input for Replicate API
52
  input_data = {
@@ -59,7 +59,7 @@ def run_single_image_logic(prompt: str, image_path: Optional[str] = None, progre
59
  data_uri = image_to_data_uri(image_path)
60
  input_data["image_input"] = [data_uri]
61
 
62
- progress(0.5, desc="โœจ ์ƒ์„ฑ ์ค‘...")
63
 
64
  # Run the model on Replicate
65
  output = replicate.run(
@@ -67,7 +67,7 @@ def run_single_image_logic(prompt: str, image_path: Optional[str] = None, progre
67
  input=input_data
68
  )
69
 
70
- progress(0.8, desc="๐Ÿ–ผ๏ธ ๋งˆ๋ฌด๋ฆฌ ์ค‘...")
71
 
72
  # Handle the output - output is already a URL string or FileObject
73
  if output:
@@ -97,7 +97,7 @@ def run_single_image_logic(prompt: str, image_path: Optional[str] = None, progre
97
  img = Image.open(BytesIO(response.content))
98
  with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmpfile:
99
  img.save(tmpfile.name)
100
- progress(1.0, desc="โœ… ์™„๋ฃŒ!")
101
  return tmpfile.name
102
  else:
103
  raise ValueError("No output received from Replicate API")
@@ -107,17 +107,17 @@ def run_single_image_logic(prompt: str, image_path: Optional[str] = None, progre
107
  print(f"Error type: {type(e)}")
108
  print(f"Output value: {output if 'output' in locals() else 'Not set'}")
109
  print(f"Output type: {type(output) if 'output' in locals() else 'Not set'}")
110
- raise gr.Error(f"์ด๋ฏธ์ง€ ์ƒ์„ฑ ์‹คํŒจ: {e}")
111
 
112
  def run_multi_image_logic(prompt: str, images: List[str], progress=gr.Progress()) -> str:
113
  """
114
  Handles multi-image editing by sending a list of images and a prompt.
115
  """
116
  if not images:
117
- raise gr.Error("'์—ฌ๋Ÿฌ ์ด๋ฏธ์ง€' ํƒญ์—์„œ ์ตœ์†Œ ํ•œ ๊ฐœ์˜ ์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œํ•ด์ฃผ์„ธ์š”.")
118
 
119
  try:
120
- progress(0.2, desc="๐ŸŽจ ์ด๋ฏธ์ง€ ์ค€๋น„ ์ค‘...")
121
 
122
  # Convert all images to data URI format
123
  data_uris = []
@@ -133,7 +133,7 @@ def run_multi_image_logic(prompt: str, images: List[str], progress=gr.Progress()
133
  "image_input": data_uris
134
  }
135
 
136
- progress(0.5, desc="โœจ ์ƒ์„ฑ ์ค‘...")
137
 
138
  # Run the model on Replicate
139
  output = replicate.run(
@@ -141,7 +141,7 @@ def run_multi_image_logic(prompt: str, images: List[str], progress=gr.Progress()
141
  input=input_data
142
  )
143
 
144
- progress(0.8, desc="๐Ÿ–ผ๏ธ ๋งˆ๋ฌด๋ฆฌ ์ค‘...")
145
 
146
  # Handle the output - output is already a URL string or FileObject
147
  if output:
@@ -171,7 +171,7 @@ def run_multi_image_logic(prompt: str, images: List[str], progress=gr.Progress()
171
  img = Image.open(BytesIO(response.content))
172
  with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmpfile:
173
  img.save(tmpfile.name)
174
- progress(1.0, desc="โœ… ์™„๋ฃŒ!")
175
  return tmpfile.name
176
  else:
177
  raise ValueError("No output received from Replicate API")
@@ -180,7 +180,7 @@ def run_multi_image_logic(prompt: str, images: List[str], progress=gr.Progress()
180
  print(f"Multi-image error details: {e}")
181
  print(f"Output value: {output if 'output' in locals() else 'Not set'}")
182
  print(f"Output type: {type(output) if 'output' in locals() else 'Not set'}")
183
- raise gr.Error(f"์ด๋ฏธ์ง€ ์ƒ์„ฑ ์‹คํŒจ: {e}")
184
 
185
  # --- Gradio App UI ---
186
  css = '''
@@ -364,7 +364,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
364
  ๐ŸŒ Real Nano Banana
365
  </h1>
366
  <p class="header-subtitle">
367
- Google Nano Banana๋กœ ๊ตฌ๋™๋˜๋Š” AI ์ด๋ฏธ์ง€ ์ƒ์„ฑ๊ธฐ
368
  </p>
369
  </div>
370
  ''')
@@ -375,7 +375,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
375
  border-radius: 0.5rem; padding: 1rem; margin-bottom: 1.5rem;
376
  border-left: 4px solid #0284c7;">
377
  <p style="margin: 0; color: #075985; font-weight: 600;">
378
- ๐Ÿ” ์ด ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด Hugging Face ๊ณ„์ •๏ฟฝ๏ฟฝ๋กœ ๋กœ๊ทธ์ธํ•ด์ฃผ์„ธ์š”.
379
  </p>
380
  </div>
381
  ''')
@@ -389,53 +389,53 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
389
  gr.HTML('<div class="card">')
390
 
391
  # Mode Selection
392
- gr.HTML('<h3 style="margin-top: 0;">๐Ÿ“ธ ๋ชจ๋“œ ์„ ํƒ</h3>')
393
  active_tab_state = gr.State(value="single")
394
 
395
  with gr.Tabs(elem_classes="tabs") as tabs:
396
- with gr.TabItem("๐Ÿ–ผ๏ธ ๋‹จ์ผ ์ด๋ฏธ์ง€", id="single") as single_tab:
397
  image_input = gr.Image(
398
  type="filepath",
399
- label="์ž…๋ ฅ ์ด๋ฏธ์ง€ (์„ ํƒ์‚ฌํ•ญ)",
400
  elem_classes="image-input"
401
  )
402
  gr.HTML('''
403
  <p style="text-align: center; color: #6b7280; font-size: 0.9rem; margin-top: 0.5rem;">
404
- ๐Ÿ’ก ํ…์ŠคํŠธโ†’์ด๋ฏธ์ง€ ์ƒ์„ฑ์€ ๋น„์›Œ๋‘์„ธ์š”
405
  </p>
406
  ''')
407
 
408
- with gr.TabItem("๐ŸŽจ ๋‹ค์ค‘ ์ด๋ฏธ์ง€", id="multiple") as multi_tab:
409
  gallery_input = gr.Gallery(
410
- label="์ž…๋ ฅ ์ด๋ฏธ์ง€๋“ค",
411
  file_types=["image"],
412
  elem_classes="gallery-input"
413
  )
414
  gr.HTML('''
415
  <p style="text-align: center; color: #6b7280; font-size: 0.9rem; margin-top: 0.5rem;">
416
- ๐Ÿ’ก ์—ฌ๋Ÿฌ ์ด๋ฏธ์ง€๋ฅผ ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญํ•˜์„ธ์š”
417
  </p>
418
  ''')
419
 
420
  # Prompt Input
421
- gr.HTML('<h3>โœ๏ธ ํ”„๋กฌํ”„ํŠธ</h3>')
422
  prompt_input = gr.Textbox(
423
  label="",
424
- info="AI์—๊ฒŒ ์›ํ•˜๋Š” ์ด๋ฏธ์ง€๋ฅผ ์„ค๋ช…ํ•˜์„ธ์š”",
425
- placeholder="์˜ˆ: ๋ง›์žˆ์–ด ๋ณด์ด๋Š” ํ”ผ์ž, ์šฐ์ฃผ๋ฅผ ๋ฐฐ๊ฒฝ์œผ๋กœ ํ•œ ๊ณ ์–‘์ด, ๋ฏธ๋ž˜์ ์ธ ๋„์‹œ ํ’๊ฒฝ...",
426
  lines=3,
427
  elem_classes="prompt-input"
428
  )
429
 
430
  # Generate Button
431
  generate_button = gr.Button(
432
- "๐Ÿš€ ์ƒ์„ฑํ•˜๊ธฐ",
433
  variant="primary",
434
  elem_classes="generate-btn"
435
  )
436
 
437
  # Examples
438
- with gr.Accordion("๐Ÿ’ก ์˜ˆ์ œ ํ”„๋กฌํ”„ํŠธ", open=False):
439
  gr.Examples(
440
  examples=[
441
  ["A delicious looking pizza with melting cheese"],
@@ -453,7 +453,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
453
 
454
  with gr.Column(scale=1):
455
  gr.HTML('<div class="card">')
456
- gr.HTML('<h3 style="margin-top: 0;">๐ŸŽจ ์ƒ์„ฑ ๊ฒฐ๊ณผ</h3>')
457
 
458
  output_image = gr.Image(
459
  label="",
@@ -462,7 +462,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
462
  )
463
 
464
  use_image_button = gr.Button(
465
- "โ™ป๏ธ ์ด ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์Œ ํŽธ์ง‘์— ์‚ฌ์šฉ",
466
  elem_classes="use-btn",
467
  visible=False
468
  )
@@ -470,12 +470,12 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
470
  # Tips
471
  gr.HTML('''
472
  <div style="background: #f0f9ff; border-radius: 0.5rem; padding: 1rem; margin-top: 1rem;">
473
- <h4 style="margin-top: 0; color: #0369a1;">๐Ÿ’ก ํŒ</h4>
474
  <ul style="margin: 0; padding-left: 1.5rem; color: #0c4a6e;">
475
- <li>๊ตฌ์ฒด์ ์ด๊ณ  ์ƒ์„ธํ•œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”</li>
476
- <li>์ƒ์„ฑ๋œ ์ด๋ฏธ์ง€๋ฅผ ์žฌ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ˜๋ณต์ ์œผ๋กœ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค</li>
477
- <li>๋‹ค์ค‘ ์ด๋ฏธ์ง€ ๋ชจ๋“œ๋กœ ์—ฌ๋Ÿฌ ์ฐธ์กฐ ์ด๋ฏธ์ง€๋ฅผ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค</li>
478
- <li>์˜์–ด ํ”„๋กฌํ”„ํŠธ๊ฐ€ ๋” ์ข‹์€ ๊ฒฐ๊ณผ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค</li>
479
  </ul>
480
  </div>
481
  ''')
@@ -503,9 +503,9 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
503
  oauth_token: Optional[gr.OAuthToken] = None,
504
  ):
505
  if not verify_login_status(oauth_token):
506
- raise gr.Error("๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ƒ๋‹จ์˜ 'Sign in with Hugging Face' ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ด์ฃผ์„ธ์š”.")
507
  if not prompt:
508
- raise gr.Error("ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.")
509
  if active_tab == "multiple" and multi_images:
510
  result = run_multi_image_logic(prompt, multi_images)
511
  else:
 
46
  def run_single_image_logic(prompt: str, image_path: Optional[str] = None, progress=gr.Progress()) -> str:
47
  """Handles text-to-image or single image-to-image using Replicate's Nano Banana."""
48
  try:
49
+ progress(0.2, desc="๐ŸŽจ Preparing...")
50
 
51
  # Prepare input for Replicate API
52
  input_data = {
 
59
  data_uri = image_to_data_uri(image_path)
60
  input_data["image_input"] = [data_uri]
61
 
62
+ progress(0.5, desc="โœจ Generating...")
63
 
64
  # Run the model on Replicate
65
  output = replicate.run(
 
67
  input=input_data
68
  )
69
 
70
+ progress(0.8, desc="๐Ÿ–ผ๏ธ Finalizing...")
71
 
72
  # Handle the output - output is already a URL string or FileObject
73
  if output:
 
97
  img = Image.open(BytesIO(response.content))
98
  with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmpfile:
99
  img.save(tmpfile.name)
100
+ progress(1.0, desc="โœ… Complete!")
101
  return tmpfile.name
102
  else:
103
  raise ValueError("No output received from Replicate API")
 
107
  print(f"Error type: {type(e)}")
108
  print(f"Output value: {output if 'output' in locals() else 'Not set'}")
109
  print(f"Output type: {type(output) if 'output' in locals() else 'Not set'}")
110
+ raise gr.Error(f"Image generation failed: {e}")
111
 
112
  def run_multi_image_logic(prompt: str, images: List[str], progress=gr.Progress()) -> str:
113
  """
114
  Handles multi-image editing by sending a list of images and a prompt.
115
  """
116
  if not images:
117
+ raise gr.Error("Please upload at least one image in the 'Multiple Images' tab.")
118
 
119
  try:
120
+ progress(0.2, desc="๐ŸŽจ Preparing images...")
121
 
122
  # Convert all images to data URI format
123
  data_uris = []
 
133
  "image_input": data_uris
134
  }
135
 
136
+ progress(0.5, desc="โœจ Generating...")
137
 
138
  # Run the model on Replicate
139
  output = replicate.run(
 
141
  input=input_data
142
  )
143
 
144
+ progress(0.8, desc="๐Ÿ–ผ๏ธ Finalizing...")
145
 
146
  # Handle the output - output is already a URL string or FileObject
147
  if output:
 
171
  img = Image.open(BytesIO(response.content))
172
  with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmpfile:
173
  img.save(tmpfile.name)
174
+ progress(1.0, desc="โœ… Complete!")
175
  return tmpfile.name
176
  else:
177
  raise ValueError("No output received from Replicate API")
 
180
  print(f"Multi-image error details: {e}")
181
  print(f"Output value: {output if 'output' in locals() else 'Not set'}")
182
  print(f"Output type: {type(output) if 'output' in locals() else 'Not set'}")
183
+ raise gr.Error(f"Image generation failed: {e}")
184
 
185
  # --- Gradio App UI ---
186
  css = '''
 
364
  ๐ŸŒ Real Nano Banana
365
  </h1>
366
  <p class="header-subtitle">
367
+ AI Image Generator powered by Google Nano Banana
368
  </p>
369
  </div>
370
  ''')
 
375
  border-radius: 0.5rem; padding: 1rem; margin-bottom: 1.5rem;
376
  border-left: 4px solid #0284c7;">
377
  <p style="margin: 0; color: #075985; font-weight: 600;">
378
+ ๐Ÿ” Please sign in with your Hugging Face account to use this service.
379
  </p>
380
  </div>
381
  ''')
 
389
  gr.HTML('<div class="card">')
390
 
391
  # Mode Selection
392
+ gr.HTML('<h3 style="margin-top: 0;">๐Ÿ“ธ Select Mode</h3>')
393
  active_tab_state = gr.State(value="single")
394
 
395
  with gr.Tabs(elem_classes="tabs") as tabs:
396
+ with gr.TabItem("๐Ÿ–ผ๏ธ Single Image", id="single") as single_tab:
397
  image_input = gr.Image(
398
  type="filepath",
399
+ label="Input Image (Optional)",
400
  elem_classes="image-input"
401
  )
402
  gr.HTML('''
403
  <p style="text-align: center; color: #6b7280; font-size: 0.9rem; margin-top: 0.5rem;">
404
+ ๐Ÿ’ก Leave empty for text-to-image generation
405
  </p>
406
  ''')
407
 
408
+ with gr.TabItem("๐ŸŽจ Multiple Images", id="multiple") as multi_tab:
409
  gallery_input = gr.Gallery(
410
+ label="Input Images",
411
  file_types=["image"],
412
  elem_classes="gallery-input"
413
  )
414
  gr.HTML('''
415
  <p style="text-align: center; color: #6b7280; font-size: 0.9rem; margin-top: 0.5rem;">
416
+ ๐Ÿ’ก Drag and drop multiple images here
417
  </p>
418
  ''')
419
 
420
  # Prompt Input
421
+ gr.HTML('<h3>โœ๏ธ Prompt</h3>')
422
  prompt_input = gr.Textbox(
423
  label="",
424
+ info="Describe what you want the AI to generate",
425
+ placeholder="e.g., A delicious pizza, a cat in space, futuristic cityscape...",
426
  lines=3,
427
  elem_classes="prompt-input"
428
  )
429
 
430
  # Generate Button
431
  generate_button = gr.Button(
432
+ "๐Ÿš€ Generate",
433
  variant="primary",
434
  elem_classes="generate-btn"
435
  )
436
 
437
  # Examples
438
+ with gr.Accordion("๐Ÿ’ก Example Prompts", open=False):
439
  gr.Examples(
440
  examples=[
441
  ["A delicious looking pizza with melting cheese"],
 
453
 
454
  with gr.Column(scale=1):
455
  gr.HTML('<div class="card">')
456
+ gr.HTML('<h3 style="margin-top: 0;">๐ŸŽจ Generated Result</h3>')
457
 
458
  output_image = gr.Image(
459
  label="",
 
462
  )
463
 
464
  use_image_button = gr.Button(
465
+ "โ™ป๏ธ Use this image for next edit",
466
  elem_classes="use-btn",
467
  visible=False
468
  )
 
470
  # Tips
471
  gr.HTML('''
472
  <div style="background: #f0f9ff; border-radius: 0.5rem; padding: 1rem; margin-top: 1rem;">
473
+ <h4 style="margin-top: 0; color: #0369a1;">๐Ÿ’ก Tips</h4>
474
  <ul style="margin: 0; padding-left: 1.5rem; color: #0c4a6e;">
475
+ <li>Use specific and detailed prompts for better results</li>
476
+ <li>You can reuse generated images for iterative improvements</li>
477
+ <li>Multiple image mode allows you to combine reference images</li>
478
+ <li>English prompts tend to produce better results</li>
479
  </ul>
480
  </div>
481
  ''')
 
503
  oauth_token: Optional[gr.OAuthToken] = None,
504
  ):
505
  if not verify_login_status(oauth_token):
506
+ raise gr.Error("Login required. Please click the 'Sign in with Hugging Face' button at the top.")
507
  if not prompt:
508
+ raise gr.Error("Please enter a prompt.")
509
  if active_tab == "multiple" and multi_images:
510
  result = run_multi_image_logic(prompt, multi_images)
511
  else: