aiqtech commited on
Commit
5f62f73
ยท
verified ยท
1 Parent(s): 4d077de

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +114 -6
app.py CHANGED
@@ -339,12 +339,13 @@ def on_change_bbox(prompts: dict[str, Any] | None):
339
  def on_change_prompt(img: Image.Image | None, prompt: str | None, bg_prompt: str | None = None):
340
  return gr.update(interactive=bool(img and prompt))
341
 
342
-
343
-
344
  def process_prompt(img: Image.Image, prompt: str, bg_prompt: str | None = None,
345
  aspect_ratio: str = "1:1", position: str = "bottom-center",
346
- scale_percent: float = 100) -> tuple[Image.Image, Image.Image]:
347
  try:
 
 
348
  if img is None or prompt.strip() == "":
349
  raise gr.Error("Please provide both image and prompt")
350
 
@@ -374,12 +375,18 @@ def process_prompt(img: Image.Image, prompt: str, bg_prompt: str | None = None,
374
  return results[1], results[2]
375
 
376
  return results[1], results[2]
 
 
 
 
 
377
  except Exception as e:
378
  print(f"Error in process_prompt: {str(e)}")
379
  raise gr.Error(str(e))
380
  finally:
381
  clear_memory()
382
-
 
383
  def process_bbox(img: Image.Image, box_input: str) -> tuple[Image.Image, Image.Image]:
384
  try:
385
  if img is None or box_input.strip() == "":
@@ -482,9 +489,63 @@ button.primary:hover {
482
  }
483
  """
484
 
485
- # UI ๊ตฌ์„ฑ
486
- # UI ๊ตฌ์„ฑ ๋ถ€๋ถ„์—์„œ process_btn์„ ์œ„๋กœ ์ด๋™ํ•˜๊ณ  position_grid.click ๋ถ€๋ถ„ ์ œ๊ฑฐ
 
 
 
487
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488
  # UI ๊ตฌ์„ฑ
489
  with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
490
  gr.HTML("""
@@ -582,6 +643,53 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
582
  height=256
583
  )
584
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
585
  # Event bindings
586
  input_image.change(
587
  fn=update_process_button,
 
339
  def on_change_prompt(img: Image.Image | None, prompt: str | None, bg_prompt: str | None = None):
340
  return gr.update(interactive=bool(img and prompt))
341
 
342
+ # process_prompt ํ•จ์ˆ˜ ์ˆ˜์ •
 
343
  def process_prompt(img: Image.Image, prompt: str, bg_prompt: str | None = None,
344
  aspect_ratio: str = "1:1", position: str = "bottom-center",
345
+ scale_percent: float = 100, text_params: dict | None = None) -> tuple[Image.Image, Image.Image]:
346
  try:
347
+
348
+
349
  if img is None or prompt.strip() == "":
350
  raise gr.Error("Please provide both image and prompt")
351
 
 
375
  return results[1], results[2]
376
 
377
  return results[1], results[2]
378
+
379
+ if text_params and text_params.get('text'):
380
+ combined = add_text_to_image(combined, text_params)
381
+
382
+ return combined, results[2]
383
  except Exception as e:
384
  print(f"Error in process_prompt: {str(e)}")
385
  raise gr.Error(str(e))
386
  finally:
387
  clear_memory()
388
+
389
+
390
  def process_bbox(img: Image.Image, box_input: str) -> tuple[Image.Image, Image.Image]:
391
  try:
392
  if img is None or box_input.strip() == "":
 
489
  }
490
  """
491
 
492
+ def add_text_with_stroke(draw, text, x, y, font, text_color, stroke_width):
493
+ """ํ…์ŠคํŠธ์— ์™ธ๊ณฝ์„ ์„ ์ถ”๊ฐ€ํ•˜๋Š” ํ—ฌํผ ํ•จ์ˆ˜"""
494
+ for adj_x in range(-stroke_width, stroke_width + 1):
495
+ for adj_y in range(-stroke_width, stroke_width + 1):
496
+ draw.text((x + adj_x, y + adj_y), text, font=font, fill=text_color)
497
 
498
+ def add_text_to_image(image, text_params):
499
+ """์ด๋ฏธ์ง€์— ํ…์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ํ•จ์ˆ˜"""
500
+ if not text_params.get('text'):
501
+ return image
502
+
503
+ if image.mode != 'RGBA':
504
+ image = image.convert('RGBA')
505
+
506
+ txt_overlay = Image.new('RGBA', image.size, (255, 255, 255, 0))
507
+ draw = ImageDraw.Draw(txt_overlay)
508
+
509
+ try:
510
+ font = ImageFont.truetype("DejaVuSans.ttf", text_params['font_size'])
511
+ except:
512
+ try:
513
+ font = ImageFont.truetype("arial.ttf", text_params['font_size'])
514
+ except:
515
+ font = ImageFont.load_default()
516
+
517
+ color_map = {
518
+ 'White': (255, 255, 255),
519
+ 'Black': (0, 0, 0),
520
+ 'Red': (255, 0, 0),
521
+ 'Green': (0, 255, 0),
522
+ 'Blue': (0, 0, 255),
523
+ 'Yellow': (255, 255, 0),
524
+ 'Purple': (128, 0, 128)
525
+ }
526
+
527
+ rgb_color = color_map.get(text_params['color'], (255, 255, 255))
528
+ text_color = (*rgb_color, text_params['opacity'])
529
+
530
+ text_bbox = draw.textbbox((0, 0), text_params['text'], font=font)
531
+ text_width = text_bbox[2] - text_bbox[0]
532
+ text_height = text_bbox[3] - text_bbox[1]
533
+
534
+ x = int((image.width - text_width) * (text_params['x_position'] / 100))
535
+ y = int((image.height - text_height) * (text_params['y_position'] / 100))
536
+
537
+ add_text_with_stroke(
538
+ draw,
539
+ text_params['text'],
540
+ x,
541
+ y,
542
+ font,
543
+ text_color,
544
+ text_params['thickness']
545
+ )
546
+
547
+ return Image.alpha_composite(image, txt_overlay)
548
+
549
  # UI ๊ตฌ์„ฑ
550
  with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
551
  gr.HTML("""
 
643
  height=256
644
  )
645
 
646
+
647
+ with gr.Row():
648
+ with gr.Column(scale=1):
649
+ # ํ…์ŠคํŠธ ์ž…๋ ฅ ์„น์…˜ ์ถ”๊ฐ€
650
+ with gr.Group(visible=True) as text_group:
651
+ text_input = gr.Textbox(label="Text to Add", placeholder="Enter text...")
652
+ font_size = gr.Slider(minimum=10, maximum=800, value=400, step=10,
653
+ label="Font Size")
654
+ thickness = gr.Slider(minimum=0, maximum=20, value=0, step=1,
655
+ label="Text Thickness")
656
+ color_dropdown = gr.Dropdown(
657
+ choices=["White", "Black", "Red", "Green", "Blue", "Yellow", "Purple"],
658
+ value="White",
659
+ label="Text Color"
660
+ )
661
+ opacity_slider = gr.Slider(minimum=0, maximum=255, value=255, step=1,
662
+ label="Opacity")
663
+ text_x_position = gr.Slider(minimum=0, maximum=100, value=50, step=1,
664
+ label="Text X Position (%)")
665
+ text_y_position = gr.Slider(minimum=0, maximum=100, value=50, step=1,
666
+ label="Text Y Position (%)")
667
+
668
+ # ์ด๋ฒคํŠธ ๋ฐ”์ธ๋”ฉ ์ˆ˜์ •
669
+ process_btn.click(
670
+ fn=process_prompt,
671
+ inputs=[
672
+ input_image,
673
+ text_prompt,
674
+ bg_prompt,
675
+ aspect_ratio,
676
+ position,
677
+ scale_slider,
678
+ # ํ…์ŠคํŠธ ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€
679
+ gr.State(lambda: {
680
+ 'text': text_input.value,
681
+ 'font_size': font_size.value,
682
+ 'thickness': thickness.value,
683
+ 'color': color_dropdown.value,
684
+ 'opacity': opacity_slider.value,
685
+ 'x_position': text_x_position.value,
686
+ 'y_position': text_y_position.value
687
+ })
688
+ ],
689
+ outputs=[combined_image, extracted_image]
690
+ )
691
+
692
+
693
  # Event bindings
694
  input_image.change(
695
  fn=update_process_button,