Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
@@ -608,7 +608,6 @@ def add_text_to_image(
|
|
608 |
"Korean Regular": "ko-Regular.ttf",
|
609 |
"Korean Son": "ko-son.ttf"
|
610 |
}.get(font_choice, "DejaVuSans.ttf")
|
611 |
-
|
612 |
font = ImageFont.truetype(font_path, int(font_size))
|
613 |
except Exception as e:
|
614 |
print(f"Font error: {str(e)}, using default")
|
@@ -625,9 +624,8 @@ def add_text_to_image(
|
|
625 |
'Purple': (128, 0, 128)
|
626 |
}.get(color, (255, 255, 255))
|
627 |
|
628 |
-
#
|
629 |
-
|
630 |
-
temp_draw = ImageDraw.Draw(temp_img)
|
631 |
text_bbox = temp_draw.textbbox((0, 0), text, font=font)
|
632 |
text_width = text_bbox[2] - text_bbox[0]
|
633 |
text_height = text_bbox[3] - text_bbox[1]
|
@@ -636,65 +634,178 @@ def add_text_to_image(
|
|
636 |
actual_x = int((width - text_width) * (x_position / 100))
|
637 |
actual_y = int((height - text_height) * (y_position / 100))
|
638 |
|
639 |
-
# ํ
์คํธ ์์ ์ค์
|
640 |
text_color = (*rgb_color, int(opacity))
|
641 |
|
|
|
|
|
642 |
if text_position_type == "Text Behind Image":
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
672 |
else:
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
695 |
|
696 |
except Exception as e:
|
697 |
-
print(f"
|
698 |
traceback.print_exc()
|
699 |
return input_image
|
700 |
|
@@ -896,6 +1007,29 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
|
|
896 |
outputs=position
|
897 |
)
|
898 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
899 |
|
900 |
# ์ด๋ฒคํธ ๋ฐ์ธ๋ฉ
|
901 |
bg_prompt.change(
|
@@ -933,27 +1067,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
|
|
933 |
queue=True
|
934 |
)
|
935 |
|
936 |
-
|
937 |
-
|
938 |
-
# ์ด๋ฒคํธ ํธ๋ค๋ฌ ์์
|
939 |
-
add_text_btn.click(
|
940 |
-
fn=add_text_to_image,
|
941 |
-
inputs=[
|
942 |
-
combined_image, # ํ์ฌ ํ์๋ ์ด๋ฏธ์ง
|
943 |
-
text_input,
|
944 |
-
font_size,
|
945 |
-
color_dropdown,
|
946 |
-
opacity_slider,
|
947 |
-
x_position,
|
948 |
-
y_position,
|
949 |
-
thickness,
|
950 |
-
text_position_type,
|
951 |
-
font_choice
|
952 |
-
],
|
953 |
-
outputs=combined_image,
|
954 |
-
show_progress=True
|
955 |
-
)
|
956 |
-
|
957 |
demo.queue(max_size=5)
|
958 |
demo.launch(
|
959 |
server_name="0.0.0.0",
|
|
|
608 |
"Korean Regular": "ko-Regular.ttf",
|
609 |
"Korean Son": "ko-son.ttf"
|
610 |
}.get(font_choice, "DejaVuSans.ttf")
|
|
|
611 |
font = ImageFont.truetype(font_path, int(font_size))
|
612 |
except Exception as e:
|
613 |
print(f"Font error: {str(e)}, using default")
|
|
|
624 |
'Purple': (128, 0, 128)
|
625 |
}.get(color, (255, 255, 255))
|
626 |
|
627 |
+
# ํ
์คํธ ํฌ๊ธฐ ๊ณ์ฐ
|
628 |
+
temp_draw = ImageDraw.Draw(Image.new('RGBA', (1, 1)))
|
|
|
629 |
text_bbox = temp_draw.textbbox((0, 0), text, font=font)
|
630 |
text_width = text_bbox[2] - text_bbox[0]
|
631 |
text_height = text_bbox[3] - text_bbox[1]
|
|
|
634 |
actual_x = int((width - text_width) * (x_position / 100))
|
635 |
actual_y = int((height - text_height) * (y_position / 100))
|
636 |
|
637 |
+
# ํ
์คํธ ์์ ์ค์
|
638 |
text_color = (*rgb_color, int(opacity))
|
639 |
|
640 |
+
print(f"Processing {text_position_type}") # ๋๋ฒ๊น
|
641 |
+
|
642 |
if text_position_type == "Text Behind Image":
|
643 |
+
print("Starting Text Behind Image process") # ๋๋ฒ๊น
|
644 |
+
|
645 |
+
# 1. ํฐ์ ๋ฐฐ๊ฒฝ ์์ฑ
|
646 |
+
background = Image.new('RGBA', (width, height), (255, 255, 255, 255))
|
647 |
+
|
648 |
+
# 2. ํ
์คํธ ๋ ์ด์ด ์์ฑ
|
649 |
+
text_layer = Image.new('RGBA', (width, height), (0, 0, 0, 0))
|
650 |
+
text_draw = ImageDraw.Draw(text_layer)
|
651 |
+
|
652 |
+
# 3. ํ
์คํธ ๊ทธ๋ฆฌ๊ธฐ
|
653 |
+
text_draw.text(
|
654 |
+
(actual_x, actual_y),
|
655 |
+
text,
|
656 |
+
font=font,
|
657 |
+
fill=text_color
|
658 |
+
)
|
659 |
+
|
660 |
+
# 4. ๋ ์ด์ด ํฉ์ฑ
|
661 |
+
result = Image.alpha_composite(background, text_layer)
|
662 |
+
result = Image.alpha_composite(result, image)
|
663 |
+
|
664 |
+
print("Text Behind Image process completed") # ๋๋ฒ๊น
|
665 |
+
return result.convert('RGB')
|
666 |
+
|
667 |
+
else: # Text Over Image
|
668 |
+
print("Starting Text Over Image process") # ๋๋ฒ๊น
|
669 |
+
|
670 |
+
# ํ
์คํธ ์ค๋ฒ๋ ์ด ์์ฑ
|
671 |
+
overlay = Image.new('RGBA', (width, height), (0, 0, 0, 0))
|
672 |
+
draw = ImageDraw.Draw(overlay)
|
673 |
+
|
674 |
+
# ํ
์คํธ ๊ทธ๋ฆฌ๊ธฐ
|
675 |
+
draw.text(
|
676 |
+
(actual_x, actual_y),
|
677 |
+
text,
|
678 |
+
font=font,
|
679 |
+
fill=text_color
|
680 |
+
)
|
681 |
+
|
682 |
+
# ์ด๋ฏธ์ง ํฉ์ฑ
|
683 |
+
result = Image.alpha_composite(image, overlay)
|
684 |
+
|
685 |
+
print("Text Over Image process completed") # ๋๋ฒ๊น
|
686 |
+
return result.convert('RGB')
|
687 |
+
|
688 |
+
except Exception as e:
|
689 |
+
print(f"Error in add_text_to_image: {str(e)}")
|
690 |
+
traceback.print_exc()
|
691 |
+
return input_imagedef add_text_to_image(
|
692 |
+
input_image,
|
693 |
+
text,
|
694 |
+
font_size,
|
695 |
+
color,
|
696 |
+
opacity,
|
697 |
+
x_position,
|
698 |
+
y_position,
|
699 |
+
thickness,
|
700 |
+
text_position_type,
|
701 |
+
font_choice
|
702 |
+
):
|
703 |
+
"""
|
704 |
+
Add text to an image with customizable properties
|
705 |
+
"""
|
706 |
+
try:
|
707 |
+
if input_image is None or text.strip() == "":
|
708 |
+
return input_image
|
709 |
+
|
710 |
+
# PIL Image ๊ฐ์ฒด๋ก ๋ณํ
|
711 |
+
if isinstance(input_image, np.ndarray):
|
712 |
+
image = Image.fromarray(input_image)
|
713 |
+
elif isinstance(input_image, Image.Image):
|
714 |
+
image = input_image.copy()
|
715 |
else:
|
716 |
+
print(f"Unexpected image type: {type(input_image)}")
|
717 |
+
return input_image
|
718 |
+
|
719 |
+
# ์ด๋ฏธ์ง๋ฅผ RGBA ๋ชจ๋๋ก ๋ณํ
|
720 |
+
image = image.convert('RGBA')
|
721 |
+
width, height = image.size
|
722 |
+
|
723 |
+
# ํฐํธ ์ค์
|
724 |
+
try:
|
725 |
+
font_path = {
|
726 |
+
"Default": "DejaVuSans.ttf",
|
727 |
+
"Korean Regular": "ko-Regular.ttf",
|
728 |
+
"Korean Son": "ko-son.ttf"
|
729 |
+
}.get(font_choice, "DejaVuSans.ttf")
|
730 |
+
font = ImageFont.truetype(font_path, int(font_size))
|
731 |
+
except Exception as e:
|
732 |
+
print(f"Font error: {str(e)}, using default")
|
733 |
+
font = ImageFont.load_default()
|
734 |
+
|
735 |
+
# ์์ ์ค์
|
736 |
+
rgb_color = {
|
737 |
+
'White': (255, 255, 255),
|
738 |
+
'Black': (0, 0, 0),
|
739 |
+
'Red': (255, 0, 0),
|
740 |
+
'Green': (0, 255, 0),
|
741 |
+
'Blue': (0, 0, 255),
|
742 |
+
'Yellow': (255, 255, 0),
|
743 |
+
'Purple': (128, 0, 128)
|
744 |
+
}.get(color, (255, 255, 255))
|
745 |
+
|
746 |
+
# ํ
์คํธ ํฌ๊ธฐ ๊ณ์ฐ
|
747 |
+
temp_draw = ImageDraw.Draw(Image.new('RGBA', (1, 1)))
|
748 |
+
text_bbox = temp_draw.textbbox((0, 0), text, font=font)
|
749 |
+
text_width = text_bbox[2] - text_bbox[0]
|
750 |
+
text_height = text_bbox[3] - text_bbox[1]
|
751 |
+
|
752 |
+
# ํ
์คํธ ์์น ๊ณ์ฐ
|
753 |
+
actual_x = int((width - text_width) * (x_position / 100))
|
754 |
+
actual_y = int((height - text_height) * (y_position / 100))
|
755 |
+
|
756 |
+
# ํ
์คํธ ์์ ์ค์
|
757 |
+
text_color = (*rgb_color, int(opacity))
|
758 |
+
|
759 |
+
print(f"Processing {text_position_type}") # ๋๋ฒ๊น
|
760 |
+
|
761 |
+
if text_position_type == "Text Behind Image":
|
762 |
+
print("Starting Text Behind Image process") # ๋๋ฒ๊น
|
763 |
+
|
764 |
+
# 1. ํฐ์ ๋ฐฐ๊ฒฝ ์์ฑ
|
765 |
+
background = Image.new('RGBA', (width, height), (255, 255, 255, 255))
|
766 |
+
|
767 |
+
# 2. ํ
์คํธ ๋ ์ด์ด ์์ฑ
|
768 |
+
text_layer = Image.new('RGBA', (width, height), (0, 0, 0, 0))
|
769 |
+
text_draw = ImageDraw.Draw(text_layer)
|
770 |
+
|
771 |
+
# 3. ํ
์คํธ ๊ทธ๋ฆฌ๊ธฐ
|
772 |
+
text_draw.text(
|
773 |
+
(actual_x, actual_y),
|
774 |
+
text,
|
775 |
+
font=font,
|
776 |
+
fill=text_color
|
777 |
+
)
|
778 |
+
|
779 |
+
# 4. ๋ ์ด์ด ํฉ์ฑ
|
780 |
+
result = Image.alpha_composite(background, text_layer)
|
781 |
+
result = Image.alpha_composite(result, image)
|
782 |
+
|
783 |
+
print("Text Behind Image process completed") # ๋๋ฒ๊น
|
784 |
+
return result.convert('RGB')
|
785 |
+
|
786 |
+
else: # Text Over Image
|
787 |
+
print("Starting Text Over Image process") # ๋๋ฒ๊น
|
788 |
+
|
789 |
+
# ํ
์คํธ ์ค๋ฒ๋ ์ด ์์ฑ
|
790 |
+
overlay = Image.new('RGBA', (width, height), (0, 0, 0, 0))
|
791 |
+
draw = ImageDraw.Draw(overlay)
|
792 |
+
|
793 |
+
# ํ
์คํธ ๊ทธ๋ฆฌ๊ธฐ
|
794 |
+
draw.text(
|
795 |
+
(actual_x, actual_y),
|
796 |
+
text,
|
797 |
+
font=font,
|
798 |
+
fill=text_color
|
799 |
+
)
|
800 |
+
|
801 |
+
# ์ด๋ฏธ์ง ํฉ์ฑ
|
802 |
+
result = Image.alpha_composite(image, overlay)
|
803 |
+
|
804 |
+
print("Text Over Image process completed") # ๋๋ฒ๊น
|
805 |
+
return result.convert('RGB')
|
806 |
|
807 |
except Exception as e:
|
808 |
+
print(f"Error in add_text_to_image: {str(e)}")
|
809 |
traceback.print_exc()
|
810 |
return input_image
|
811 |
|
|
|
1007 |
outputs=position
|
1008 |
)
|
1009 |
|
1010 |
+
add_text_btn.click(
|
1011 |
+
fn=add_text_to_image,
|
1012 |
+
inputs=[
|
1013 |
+
combined_image,
|
1014 |
+
text_input,
|
1015 |
+
font_size,
|
1016 |
+
color_dropdown,
|
1017 |
+
opacity_slider,
|
1018 |
+
x_position,
|
1019 |
+
y_position,
|
1020 |
+
thickness,
|
1021 |
+
text_position_type,
|
1022 |
+
font_choice
|
1023 |
+
],
|
1024 |
+
outputs=combined_image,
|
1025 |
+
show_progress=True
|
1026 |
+
).then(
|
1027 |
+
lambda: None, # ์ถ๊ฐ ์์
์ด ํ์ํ ๊ฒฝ์ฐ ์ฌ๊ธฐ์ ํจ์๋ฅผ ๋ฃ์ ์ ์์ต๋๋ค
|
1028 |
+
None,
|
1029 |
+
None,
|
1030 |
+
_js="() => {console.log('Text addition completed');}" # ๋๋ฒ๊น
์ฉ JavaScript
|
1031 |
+
)
|
1032 |
+
|
1033 |
|
1034 |
# ์ด๋ฒคํธ ๋ฐ์ธ๋ฉ
|
1035 |
bg_prompt.change(
|
|
|
1067 |
queue=True
|
1068 |
)
|
1069 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1070 |
demo.queue(max_size=5)
|
1071 |
demo.launch(
|
1072 |
server_name="0.0.0.0",
|