aiqtech commited on
Commit
39fdf83
·
verified ·
1 Parent(s): 5f62f73

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +110 -106
app.py CHANGED
@@ -20,6 +20,7 @@ from transformers import GroundingDinoForObjectDetection, GroundingDinoProcessor
20
  from diffusers import FluxPipeline
21
  from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqLM
22
  import gc
 
23
 
24
  def clear_memory():
25
  """메모리 정리 함수"""
@@ -339,16 +340,14 @@ 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
- # 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
 
 
352
  print(f"Processing with position: {position}, scale: {scale_percent}")
353
 
354
  try:
@@ -358,6 +357,7 @@ def process_prompt(img: Image.Image, prompt: str, bg_prompt: str | None = None,
358
  except Exception as e:
359
  print(f"Translation error (continuing with original text): {str(e)}")
360
 
 
361
  results, _ = _process(img, prompt, bg_prompt, aspect_ratio)
362
 
363
  if bg_prompt:
@@ -368,14 +368,13 @@ def process_prompt(img: Image.Image, prompt: str, bg_prompt: str | None = None,
368
  position=position,
369
  scale_percent=scale_percent
370
  )
371
- print(f"Combined image created with position: {position}")
372
- return combined, results[2]
373
  except Exception as e:
374
  print(f"Combination error: {str(e)}")
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
 
@@ -386,7 +385,6 @@ def process_prompt(img: Image.Image, prompt: str, bg_prompt: str | None = None,
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() == "":
@@ -556,6 +554,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
556
  """)
557
 
558
  with gr.Row():
 
559
  with gr.Column(scale=1):
560
  input_image = gr.Image(
561
  type="pil",
@@ -567,6 +566,8 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
567
  placeholder="Enter what you want to extract...",
568
  interactive=True
569
  )
 
 
570
  with gr.Row():
571
  bg_prompt = gr.Textbox(
572
  label="Background Prompt (optional)",
@@ -583,10 +584,12 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
583
  scale=1
584
  )
585
 
 
586
  with gr.Row(visible=False) as object_controls:
 
587
  with gr.Column(scale=1):
 
588
  with gr.Row():
589
- position = gr.State(value="bottom-center")
590
  btn_top_left = gr.Button("↖")
591
  btn_top_center = gr.Button("↑")
592
  btn_top_right = gr.Button("↗")
@@ -598,6 +601,8 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
598
  btn_bottom_left = gr.Button("↙")
599
  btn_bottom_center = gr.Button("↓")
600
  btn_bottom_right = gr.Button("↘")
 
 
601
  with gr.Column(scale=1):
602
  scale_slider = gr.Slider(
603
  minimum=10,
@@ -607,65 +612,99 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
607
  label="Object Size (%)"
608
  )
609
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
610
  process_btn = gr.Button(
611
  "Process",
612
  variant="primary",
613
  interactive=False
614
  )
615
 
616
- # 버튼에 대한 클릭 이벤트 처리
617
- def update_position(new_position):
618
- return new_position
619
-
620
- btn_top_left.click(fn=lambda: update_position("top-left"), outputs=position)
621
- btn_top_center.click(fn=lambda: update_position("top-center"), outputs=position)
622
- btn_top_right.click(fn=lambda: update_position("top-right"), outputs=position)
623
- btn_middle_left.click(fn=lambda: update_position("middle-left"), outputs=position)
624
- btn_middle_center.click(fn=lambda: update_position("middle-center"), outputs=position)
625
- btn_middle_right.click(fn=lambda: update_position("middle-right"), outputs=position)
626
- btn_bottom_left.click(fn=lambda: update_position("bottom-left"), outputs=position)
627
- btn_bottom_center.click(fn=lambda: update_position("bottom-center"), outputs=position)
628
- btn_bottom_right.click(fn=lambda: update_position("bottom-right"), outputs=position)
629
-
630
  with gr.Column(scale=1):
631
- with gr.Row():
632
- combined_image = gr.Image(
633
- label="Combined Result",
634
- show_download_button=True,
635
- type="pil",
636
- height=512
637
- )
638
- with gr.Row():
639
- extracted_image = gr.Image(
640
- label="Extracted Object",
641
- show_download_button=True,
642
- type="pil",
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=[
@@ -675,70 +714,35 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
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,
696
  inputs=[input_image, text_prompt],
697
- outputs=process_btn,
698
- queue=False
699
  )
700
 
701
  text_prompt.change(
702
  fn=update_process_button,
703
  inputs=[input_image, text_prompt],
704
- outputs=process_btn,
705
- queue=False
706
  )
707
 
708
- def update_controls(bg_prompt):
709
- """배경 프롬프트 입력 여부에 따라 컨트롤 표시 업데이트"""
710
- is_visible = bool(bg_prompt)
711
- return [
712
- gr.update(visible=is_visible), # aspect_ratio
713
- gr.update(visible=is_visible), # object_controls
714
- ]
715
-
716
  bg_prompt.change(
717
  fn=update_controls,
718
- inputs=bg_prompt,
719
- outputs=[aspect_ratio, object_controls],
720
- queue=False
721
  )
722
 
723
- process_btn.click(
724
- fn=process_prompt,
725
- inputs=[
726
- input_image,
727
- text_prompt,
728
- bg_prompt,
729
- aspect_ratio,
730
- position,
731
- scale_slider
732
- ],
733
- outputs=[combined_image, extracted_image],
734
- queue=True
735
- )
736
-
737
-
738
- demo.queue(max_size=5) # 큐 크기 제한
739
  demo.launch(
740
  server_name="0.0.0.0",
741
  server_port=7860,
742
  share=False,
743
- max_threads=2 # 스레드 수 제한
744
- )
 
20
  from diffusers import FluxPipeline
21
  from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqLM
22
  import gc
23
+ from PIL import Image, ImageDraw, ImageFont
24
 
25
  def clear_memory():
26
  """메모리 정리 함수"""
 
340
  def on_change_prompt(img: Image.Image | None, prompt: str | None, bg_prompt: str | None = None):
341
  return gr.update(interactive=bool(img and prompt))
342
 
 
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
  if img is None or prompt.strip() == "":
348
  raise gr.Error("Please provide both image and prompt")
349
 
350
+
351
  print(f"Processing with position: {position}, scale: {scale_percent}")
352
 
353
  try:
 
357
  except Exception as e:
358
  print(f"Translation error (continuing with original text): {str(e)}")
359
 
360
+ # 기존 처리 로직...
361
  results, _ = _process(img, prompt, bg_prompt, aspect_ratio)
362
 
363
  if bg_prompt:
 
368
  position=position,
369
  scale_percent=scale_percent
370
  )
 
 
371
  except Exception as e:
372
  print(f"Combination error: {str(e)}")
373
+ combined = results[1]
374
+ else:
375
+ combined = results[1]
376
 
377
+ # 텍스트 추가 로직을 여기로 이동
378
  if text_params and text_params.get('text'):
379
  combined = add_text_to_image(combined, text_params)
380
 
 
385
  finally:
386
  clear_memory()
387
 
 
388
  def process_bbox(img: Image.Image, box_input: str) -> tuple[Image.Image, Image.Image]:
389
  try:
390
  if img is None or box_input.strip() == "":
 
554
  """)
555
 
556
  with gr.Row():
557
+ # 입력 컬럼
558
  with gr.Column(scale=1):
559
  input_image = gr.Image(
560
  type="pil",
 
566
  placeholder="Enter what you want to extract...",
567
  interactive=True
568
  )
569
+
570
+ # 배경 및 비율 설정
571
  with gr.Row():
572
  bg_prompt = gr.Textbox(
573
  label="Background Prompt (optional)",
 
584
  scale=1
585
  )
586
 
587
+ # 오브젝트 컨트롤
588
  with gr.Row(visible=False) as object_controls:
589
+ # 위치 컨트롤
590
  with gr.Column(scale=1):
591
+ position = gr.State(value="bottom-center")
592
  with gr.Row():
 
593
  btn_top_left = gr.Button("↖")
594
  btn_top_center = gr.Button("↑")
595
  btn_top_right = gr.Button("↗")
 
601
  btn_bottom_left = gr.Button("↙")
602
  btn_bottom_center = gr.Button("↓")
603
  btn_bottom_right = gr.Button("↘")
604
+
605
+ # 크기 컨트롤
606
  with gr.Column(scale=1):
607
  scale_slider = gr.Slider(
608
  minimum=10,
 
612
  label="Object Size (%)"
613
  )
614
 
615
+ # 텍스트 입력 섹션
616
+ with gr.Group() as text_group:
617
+ text_input = gr.Textbox(
618
+ label="Text to Add",
619
+ placeholder="Enter text..."
620
+ )
621
+ with gr.Row():
622
+ with gr.Column(scale=1):
623
+ font_size = gr.Slider(
624
+ minimum=10,
625
+ maximum=800,
626
+ value=400,
627
+ step=10,
628
+ label="Font Size"
629
+ )
630
+ thickness = gr.Slider(
631
+ minimum=0,
632
+ maximum=20,
633
+ value=0,
634
+ step=1,
635
+ label="Text Thickness"
636
+ )
637
+ color_dropdown = gr.Dropdown(
638
+ choices=["White", "Black", "Red", "Green", "Blue", "Yellow", "Purple"],
639
+ value="White",
640
+ label="Text Color"
641
+ )
642
+ with gr.Column(scale=1):
643
+ opacity_slider = gr.Slider(
644
+ minimum=0,
645
+ maximum=255,
646
+ value=255,
647
+ step=1,
648
+ label="Opacity"
649
+ )
650
+ text_x_position = gr.Slider(
651
+ minimum=0,
652
+ maximum=100,
653
+ value=50,
654
+ step=1,
655
+ label="Text X Position (%)"
656
+ )
657
+ text_y_position = gr.Slider(
658
+ minimum=0,
659
+ maximum=100,
660
+ value=50,
661
+ step=1,
662
+ label="Text Y Position (%)"
663
+ )
664
+
665
+ # 처리 버튼
666
  process_btn = gr.Button(
667
  "Process",
668
  variant="primary",
669
  interactive=False
670
  )
671
 
672
+ # 출력 컬럼
 
 
 
 
 
 
 
 
 
 
 
 
 
673
  with gr.Column(scale=1):
674
+ combined_image = gr.Image(
675
+ label="Combined Result",
676
+ show_download_button=True,
677
+ type="pil",
678
+ height=512
679
+ )
680
+ extracted_image = gr.Image(
681
+ label="Extracted Object",
682
+ show_download_button=True,
683
+ type="pil",
684
+ height=256
685
+ )
 
 
686
 
687
+ # 이벤트 핸들러
688
+ def get_text_params():
689
+ return {
690
+ 'text': text_input.value,
691
+ 'font_size': font_size.value,
692
+ 'thickness': thickness.value,
693
+ 'color': color_dropdown.value,
694
+ 'opacity': opacity_slider.value,
695
+ 'x_position': text_x_position.value,
696
+ 'y_position': text_y_position.value
697
+ }
698
+
699
+ # 위치 버튼 이벤트
700
+ for btn, pos in [
701
+ (btn_top_left, "top-left"), (btn_top_center, "top-center"), (btn_top_right, "top-right"),
702
+ (btn_middle_left, "middle-left"), (btn_middle_center, "middle-center"), (btn_middle_right, "middle-right"),
703
+ (btn_bottom_left, "bottom-left"), (btn_bottom_center, "bottom-center"), (btn_bottom_right, "bottom-right")
704
+ ]:
705
+ btn.click(fn=lambda p=pos: p, outputs=position)
706
+
707
+ # 메인 프로세스 이벤트
 
 
708
  process_btn.click(
709
  fn=process_prompt,
710
  inputs=[
 
714
  aspect_ratio,
715
  position,
716
  scale_slider,
717
+ gr.State(get_text_params)
 
 
 
 
 
 
 
 
 
718
  ],
719
  outputs=[combined_image, extracted_image]
720
  )
721
 
722
+ # UI 업데이트 이벤트
 
723
  input_image.change(
724
  fn=update_process_button,
725
  inputs=[input_image, text_prompt],
726
+ outputs=process_btn
 
727
  )
728
 
729
  text_prompt.change(
730
  fn=update_process_button,
731
  inputs=[input_image, text_prompt],
732
+ outputs=process_btn
 
733
  )
734
 
 
 
 
 
 
 
 
 
735
  bg_prompt.change(
736
  fn=update_controls,
737
+ inputs=[bg_prompt],
738
+ outputs=[aspect_ratio, object_controls]
 
739
  )
740
 
741
+ # 런처 설정
742
+ demo.queue(max_size=5)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
743
  demo.launch(
744
  server_name="0.0.0.0",
745
  server_port=7860,
746
  share=False,
747
+ max_threads=2
748
+ )