|
import os |
|
import sys |
|
import base64 |
|
import io |
|
import logging |
|
import tempfile |
|
import traceback |
|
import requests |
|
from PIL import Image |
|
import gradio as gr |
|
from gradio_client import Client, handle_file |
|
from dotenv import load_dotenv |
|
|
|
|
|
load_dotenv() |
|
|
|
|
|
logging.basicConfig( |
|
level=logging.INFO, |
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', |
|
handlers=[ |
|
logging.FileHandler("app.log"), |
|
logging.StreamHandler(sys.stdout) |
|
] |
|
) |
|
logger = logging.getLogger("image-enhancer-app") |
|
|
|
|
|
API_ENDPOINT = os.environ.get("API_ENDPOINT") |
|
if not API_ENDPOINT: |
|
logger.error("API_ENDPOINT environment variable is not set") |
|
sys.exit(1) |
|
|
|
try: |
|
|
|
api_client = Client(API_ENDPOINT) |
|
logger.info("API client initialized successfully") |
|
except Exception as e: |
|
logger.error(f"Failed to initialize API client: {e}") |
|
sys.exit(1) |
|
|
|
|
|
def load_backgrounds_from_env(): |
|
"""ํ๊ฒฝ๋ณ์์์ backgrounds.py ์ ์ฒด ๋ด์ฉ ๋ก๋""" |
|
backgrounds_code = os.environ.get("BACKGROUNDS_DATA", "") |
|
if not backgrounds_code: |
|
logger.warning("BACKGROUNDS_DATA environment variable is empty") |
|
return {}, {}, {}, {}, {}, {}, {} |
|
|
|
try: |
|
|
|
local_vars = {} |
|
exec(backgrounds_code, {}, local_vars) |
|
|
|
return ( |
|
local_vars.get("SIMPLE_BACKGROUNDS", {}), |
|
local_vars.get("STUDIO_BACKGROUNDS", {}), |
|
local_vars.get("NATURE_BACKGROUNDS", {}), |
|
local_vars.get("INDOOR_BACKGROUNDS", {}), |
|
local_vars.get("SPECIAL_BACKGROUNDS", {}), |
|
local_vars.get("JEWELRY_BACKGROUNDS", {}), |
|
local_vars.get("SPECIAL_EFFECTS_BACKGROUNDS", {}) |
|
) |
|
except Exception as e: |
|
logger.error(f"Failed to parse BACKGROUNDS_DATA: {e}") |
|
return {}, {}, {}, {}, {}, {}, {} |
|
|
|
|
|
(SIMPLE_BACKGROUNDS, STUDIO_BACKGROUNDS, NATURE_BACKGROUNDS, |
|
INDOOR_BACKGROUNDS, SPECIAL_BACKGROUNDS, JEWELRY_BACKGROUNDS, |
|
SPECIAL_EFFECTS_BACKGROUNDS) = load_backgrounds_from_env() |
|
|
|
|
|
if not SIMPLE_BACKGROUNDS: |
|
SIMPLE_BACKGROUNDS = { |
|
"ํ์ดํธ ๊ธฐ๋ณธ": "clean white background with soft lighting", |
|
"ํ์ ํฌํค": "light gray background with minimal shadows", |
|
"๋ผ์ดํธ ๊ทธ๋ ์ด": "soft light gray backdrop with even illumination", |
|
"๊ทธ๋ ์ด ๊ทธ๋ผ๋ฐ์ด์
์คํฌํธ๋ผ์ดํธ": "gray gradient with spotlight", |
|
"ํ๋ฆฌ๋ฏธ์ ๋๋ผ๋งํฑ ๋ธ๋": "premium dramatic black background", |
|
"๋ฅ๋ธ๋ฃจ ์ ๋ฆฌ๋ฐ์ฌ": "deep blue glass reflection", |
|
"ํ์คํ
๊ทธ๋ผ๋ฐ์ด์
": "pastel gradient background", |
|
"์ค์นด์ด๋ธ๋ฃจ ํ์คํ
": "sky blue pastel", |
|
"๋ฒํฐ์๋ก์ฐ ํ์คํ
": "butter yellow pastel", |
|
"๋ธ๋ฃจ ์์": "pure blue background", |
|
"๋ ๋ ์์": "pure red background" |
|
} |
|
|
|
if not STUDIO_BACKGROUNDS: |
|
STUDIO_BACKGROUNDS = { |
|
"์ฐ๋
น์ ์ฅ๋ฏธ ์ ์": "soft green rose garden", |
|
"์ฐ๋ถํ ์ฅ๋ฏธ ๋๋ฆฌ์": "pink rose with marble", |
|
"ํ์คํ
๋ธ๋ฃจ ์๊ตญ": "pastel blue hydrangea", |
|
"์ํํธ ํํฌ ๋ฒ๊ฝ": "soft pink cherry blossom", |
|
"ํ์คํ
์๋ก์ฐ ๊ฝ๋ด์ค๋ฆฌ": "pastel yellow buds", |
|
"์์ด๋ณด๋ฆฌ ๋ก์ฆ ์ฌํ": "ivory rose simple", |
|
"์ฌํ ํ์ดํธ ์์ ํ๋ถ": "simple white small pot", |
|
"ํผํ ์ฅ๋์ค๋ฌ์ด ์ฌ๋น๋ก์ด ๋ถ์๊ธฐ": "purple playful mood", |
|
"์ฝ์ง ๋ฐ์คํฌ ํ๋ํธ": "cozy desk plant", |
|
"์ฐํํฌ ํค๋ฆฝ ์์ํ
์ด๋ธ": "light pink tulip small table", |
|
"์คํฌ์ฐ๋ ํค๋ฆฝ ์ค์ ํธํ": "oak wood tulip shower puff", |
|
"ํฌ๋ฆผ ์ฝํผ": "cream cotton", |
|
"๋ธ๋ผ์ด ๊ฑฐ์น ํ์ดํผ": "brown rough paper" |
|
} |
|
|
|
if not NATURE_BACKGROUNDS: |
|
NATURE_BACKGROUNDS = { |
|
"์์ ํ๋๊ฐ ์๋ ํด๋ณ": "beach with small waves", |
|
"ํญ๊ท์ด ์๋ ๋น์ฐ": "iceberg with penguin", |
|
"๋๋ด๋ฆฌ๋ ์ฐ์
์ค์": "snowy mountain field", |
|
"์ด๋ํด๋ณ": "tropical beach", |
|
"์ผ์ถ ์ง์ ์ ๋ฐ์์ฐ": "rocky mountain before sunrise", |
|
"์ด๊ทผ์ ๋ด๊ฝ ๋คํ": "close-up spring flower field", |
|
"๋ฌผ๊ฐ ๋ฐ์": "waterside rocks", |
|
"์์ ๋์ด ๊น๋ฆฐ ์์ ๋ฌผ๊ฐ": "shallow water with small stones", |
|
"๋๋ฌด ํ
์ด๋ธ ์ฒ์ ๊ณ๊ณก": "wooden table forest valley", |
|
"์๊ฐ ๋ ์ฒ": "foggy forest", |
|
"์ผ๋ชฐ ๋ฐ๋ค": "sunset sea", |
|
"๋ณ์ด ๋น๋๋ ์บ ํ": "starry camping" |
|
} |
|
|
|
if not INDOOR_BACKGROUNDS: |
|
INDOOR_BACKGROUNDS = { |
|
"๊ธฐ๋ณธ ์ฑ
์": "basic desk", |
|
"๋น์ด ๋น์น๋ ์ฑ
์": "desk with light", |
|
"๋น์ด ๋น์น๋ ๊ฑฐ์ค": "living room with light", |
|
"์คํ๋์ด ๊ฑฐ์ค": "studio living room", |
|
"ํ๋ถ์ด ์๋ ๊ฑฐ์ค": "living room with plants", |
|
"์ ์ฒด์ ์ธ ๊ฑฐ์ค๋ชจ์ต": "overall living room view", |
|
"ํฌ์ธํธ ๊ฑฐ์ค": "point living room", |
|
"์ค์ ๊ฑฐ์ค": "central living room", |
|
"์๋ํ
์ด๋ธ": "drawer table", |
|
"์นจ์ค ํ์์": "bedroom table top", |
|
"์๋ชฉ ํ
์ด๋ธ ๋ธ๋ก": "wood table block", |
|
"ํ
์ด๋ธ ์ฌํ": "simple table", |
|
"๋ถ์๊ธฐ ์๋ ์นจ์ค": "atmospheric bedroom", |
|
"๋๋ฌดํ
์ด๋ธ์": "on wooden table", |
|
"์ฑ
์ ๊ฑฐ์คํ
์ด๋ธ": "living room table with books", |
|
"์ ๋ฆฌํ
์ด๋ธ์": "on glass table", |
|
"์นจ์ค ์ ์์ํ์": "small bedside table", |
|
"๋ถ์๊ธฐ ์๋ ์ํ ํ
์ด๋ธ": "atmospheric round table", |
|
"ํฌ์ปค์ค ํ์": "focus table", |
|
"ํฌํค ๋ฒฝ๋ฉด": "two-tone wall", |
|
"์๋ํ ํ
์ด๋ธ์ ์ก์ธ์๋ฆฌ": "cozy table accessories", |
|
"์๋ํ ํ
์ด๋ธ ๋ณด ์": "on cozy tablecloth", |
|
"์ ๋ฆฌ ๋ฐ๋ฅ": "glass floor", |
|
"๋น์น๋ ์ํ์": "dining table with light", |
|
"๋๋ํ ์ํ์ ์์
๋": "cozy dining workspace" |
|
} |
|
|
|
if not SPECIAL_BACKGROUNDS: |
|
SPECIAL_BACKGROUNDS = { |
|
"๋ค์ด๋น ๋นํฐ์ง ํ๋ก๋ด ๋ฒฝ์ง": "navy vintage floral wallpaper", |
|
"๋นํฐ์ง ๊ฝ๋ฌด๋ฌ ํจ๋ธ๋ฆญ ๋ฐฐ๊ฒฝ": "vintage floral fabric background", |
|
"ํ ๋ํธ์ ๊ณผ์ผ": "pop dots and fruits", |
|
"๋ธ๋ฃจ ๋ง๋ธ ์ํฌ ํ
์ค์ฒ ๋ฐฐ๊ฒฝ": "blue marble ink texture", |
|
"์ค๋ ์ง๋ธ๋ฃจ ์ํฐ์ปฌ๋ฌ ๋ฐฐ๊ฒฝ": "orange blue watercolor", |
|
"๋ ๋๋ธ๋ฌ์ ํ์ธํ
์ํธ ๋ฐฐ๊ฒฝ": "red brush painting art", |
|
"๋ธ๋ฃจ์ค๋ ์ง ํ์ธํ
์ํธ": "blue orange painting art" |
|
} |
|
|
|
if not JEWELRY_BACKGROUNDS: |
|
JEWELRY_BACKGROUNDS = { |
|
"ํ์ดํธ ๋ฏธ๋ฌ ์คํ ๋ผ์ดํธ": "white mirror spotlight", |
|
"๊ทธ๋ ์ด ๊ทธ๋ผ๋ฐ์ด์
๋ฏธ๋ฌ": "gray gradient mirror", |
|
"๋ค์ด๋น ๋ฒจ๋ฒณ": "navy velvet", |
|
"๋ธ๋ ๋ฏธ๋ฌ ์๋ค๋งํฑ": "black mirror cinematic", |
|
"ํ์ดํธ ๋ง๋ธ ํ๋ฆฌ๋ฏธ์": "white marble premium", |
|
"ํ์คํ
๋ธ๋ฃจ ํ๋ธ ํ๋ซํผ": "pastel blue cube platform", |
|
"๋ด์ถ๋ด ๊ทธ๋ผ์ค": "natural grass", |
|
"์ํํธ ๋ฒ ์ด์ง ํจ๋ธ๋ฆญ": "soft basic fabric", |
|
"๋ง์ดํฌ๋กํ
์ค์ณ ํ๋ฆฌ๋ฏธ์": "micro texture premium" |
|
} |
|
|
|
if not SPECIAL_EFFECTS_BACKGROUNDS: |
|
SPECIAL_EFFECTS_BACKGROUNDS = { |
|
"๋ธ๋ฃจ๋ธ๋ ํฐ ๋ฌผ๋ฐฉ์ธ ํจ๊ณผ": "blue black water drop effect", |
|
"ํฌ๋ฆฌ์คํ ๋ฒ๋ธ ๋ฌผ์ ์ฅ๋ฉด": "crystal bubble underwater scene", |
|
"์ ๋ฌผ๊ฒฐ ์๋ฉด ์ ์ฅ๋ฉด": "gentle ripple water surface scene", |
|
"์ปฌ๋ฌ ์ค๋ชจํฌ ํจ๊ณผ": "color smoke effect", |
|
"์์ฅํ ์๊ฐ ํจ๊ณผ": "dense fog effect", |
|
"๊ฐ์ต๊ธฐ ์์ค๊ธฐ ํจ๊ณผ": "humidifier mist effect" |
|
} |
|
|
|
|
|
def save_uploaded_file(uploaded_file, suffix='.png'): |
|
try: |
|
logger.info(f"Processing uploaded file: {type(uploaded_file)}") |
|
|
|
if uploaded_file is None: |
|
logger.warning("Uploaded file is None") |
|
return None |
|
|
|
with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as temp_file: |
|
temp_filename = temp_file.name |
|
logger.info(f"Created temporary file: {temp_filename}") |
|
|
|
|
|
if isinstance(uploaded_file, str): |
|
logger.info(f"Uploaded file is already a path: {uploaded_file}") |
|
return uploaded_file |
|
|
|
|
|
if isinstance(uploaded_file, Image.Image): |
|
logger.info("Uploaded file is a PIL Image") |
|
uploaded_file.save(temp_filename, format="PNG") |
|
return temp_filename |
|
|
|
|
|
with open(temp_filename, "wb") as f: |
|
if hasattr(uploaded_file, "read"): |
|
logger.info("Processing file object") |
|
content = uploaded_file.read() |
|
f.write(content) |
|
logger.info(f"Wrote {len(content)} bytes to {temp_filename}") |
|
else: |
|
logger.info("Processing binary data") |
|
f.write(uploaded_file) |
|
logger.info(f"Wrote data to {temp_filename}") |
|
|
|
return temp_filename |
|
except Exception as e: |
|
logger.error(f"Error saving uploaded file: {e}") |
|
logger.error(traceback.format_exc()) |
|
return None |
|
|
|
|
|
def create_gradio_interface(): |
|
try: |
|
logger.info("Creating Gradio interface") |
|
with gr.Blocks(title="AI ์ด๋ฏธ์ง ํธ์ง ๋ฐ ํ์ง ๊ฐ์ ") as app: |
|
gr.Markdown("# AI ์ด๋ฏธ์ง ํธ์ง ๋ฐ ํ์ง ๊ฐ์ ๋๊ตฌ") |
|
|
|
|
|
password_box = gr.Textbox( |
|
label="๋น๋ฐ๋ฒํธ", |
|
type="password", |
|
placeholder="์ฌ์ฉํ๋ ค๋ฉด ๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํ์ธ์", |
|
interactive=True |
|
) |
|
|
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
|
|
image = gr.Image(label="์ํ ์ด๋ฏธ์ง ์
๋ก๋", type="pil") |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
background_type = gr.Radio( |
|
choices=["์ฌํ ๋ฐฐ๊ฒฝ", "์คํ๋์ค ๋ฐฐ๊ฒฝ", "์์ฐ ํ๊ฒฝ", "์ค๋ด ํ๊ฒฝ", "ํน์๋ฐฐ๊ฒฝ", "์ฃผ์ผ๋ฆฌ", "ํน์ํจ๊ณผ"], |
|
label="๋ฐฐ๊ฒฝ ์ ํ", |
|
value="์ฌํ ๋ฐฐ๊ฒฝ" |
|
) |
|
|
|
|
|
simple_dropdown = gr.Dropdown( |
|
choices=list(SIMPLE_BACKGROUNDS.keys()), |
|
value=list(SIMPLE_BACKGROUNDS.keys())[0] if SIMPLE_BACKGROUNDS else None, |
|
label="์ฌํ ๋ฐฐ๊ฒฝ ์ ํ", |
|
visible=True, |
|
interactive=True |
|
) |
|
|
|
studio_dropdown = gr.Dropdown( |
|
choices=list(STUDIO_BACKGROUNDS.keys()), |
|
value=list(STUDIO_BACKGROUNDS.keys())[0] if STUDIO_BACKGROUNDS else None, |
|
label="์คํ๋์ค ๋ฐฐ๊ฒฝ ์ ํ", |
|
visible=False, |
|
interactive=True |
|
) |
|
|
|
nature_dropdown = gr.Dropdown( |
|
choices=list(NATURE_BACKGROUNDS.keys()), |
|
value=list(NATURE_BACKGROUNDS.keys())[0] if NATURE_BACKGROUNDS else None, |
|
label="์์ฐ ํ๊ฒฝ ์ ํ", |
|
visible=False, |
|
interactive=True |
|
) |
|
|
|
indoor_dropdown = gr.Dropdown( |
|
choices=list(INDOOR_BACKGROUNDS.keys()), |
|
value=list(INDOOR_BACKGROUNDS.keys())[0] if INDOOR_BACKGROUNDS else None, |
|
label="์ค๋ด ํ๊ฒฝ ์ ํ", |
|
visible=False, |
|
interactive=True |
|
) |
|
|
|
special_dropdown = gr.Dropdown( |
|
choices=list(SPECIAL_BACKGROUNDS.keys()), |
|
value=list(SPECIAL_BACKGROUNDS.keys())[0] if SPECIAL_BACKGROUNDS else None, |
|
label="ํน์๋ฐฐ๊ฒฝ ์ ํ", |
|
visible=False, |
|
interactive=True |
|
) |
|
|
|
jewelry_dropdown = gr.Dropdown( |
|
choices=list(JEWELRY_BACKGROUNDS.keys()), |
|
value=list(JEWELRY_BACKGROUNDS.keys())[0] if JEWELRY_BACKGROUNDS else None, |
|
label="์ฃผ์ผ๋ฆฌ ๋ฐฐ๊ฒฝ ์ ํ", |
|
visible=False, |
|
interactive=True |
|
) |
|
|
|
special_effects_dropdown = gr.Dropdown( |
|
choices=list(SPECIAL_EFFECTS_BACKGROUNDS.keys()), |
|
value=list(SPECIAL_EFFECTS_BACKGROUNDS.keys())[0] if SPECIAL_EFFECTS_BACKGROUNDS else None, |
|
label="ํน์ํจ๊ณผ ๋ฐฐ๊ฒฝ ์ ํ", |
|
visible=False, |
|
interactive=True |
|
) |
|
|
|
|
|
def update_dropdowns(bg_type): |
|
try: |
|
|
|
result = api_client.predict(bg_type=bg_type, api_name="/update_dropdowns") |
|
return result |
|
except: |
|
|
|
return { |
|
simple_dropdown: gr.update(visible=(bg_type == "์ฌํ ๋ฐฐ๊ฒฝ")), |
|
studio_dropdown: gr.update(visible=(bg_type == "์คํ๋์ค ๋ฐฐ๊ฒฝ")), |
|
nature_dropdown: gr.update(visible=(bg_type == "์์ฐ ํ๊ฒฝ")), |
|
indoor_dropdown: gr.update(visible=(bg_type == "์ค๋ด ํ๊ฒฝ")), |
|
special_dropdown: gr.update(visible=(bg_type == "ํน์๋ฐฐ๊ฒฝ")), |
|
jewelry_dropdown: gr.update(visible=(bg_type == "์ฃผ์ผ๋ฆฌ")), |
|
special_effects_dropdown: gr.update(visible=(bg_type == "ํน์ํจ๊ณผ")) |
|
} |
|
|
|
background_type.change( |
|
fn=update_dropdowns, |
|
inputs=[background_type], |
|
outputs=[simple_dropdown, studio_dropdown, nature_dropdown, indoor_dropdown, special_dropdown, jewelry_dropdown, special_effects_dropdown], |
|
api_name="update_dropdowns" |
|
) |
|
|
|
|
|
request_text = gr.Textbox( |
|
label="์์ฒญ์ฌํญ", |
|
placeholder="์ํ ์ด๋ฏธ์ง์ ์ ์ฉํ ์คํ์ผ, ๋ถ์๊ธฐ, ํน๋ณ ์์ฒญ์ฌํญ ๋ฑ์ ์
๋ ฅํ์ธ์.", |
|
lines=3 |
|
) |
|
|
|
|
|
quality_level = gr.Radio( |
|
label="ํ์ง ๋ ๋ฒจ", |
|
choices=["gpt", "flux"], |
|
value="flux", |
|
info="GPT: GPT ๋ชจ๋ธ (๊ณ ํ์ง), ์ผ๋ฐ: Flux ๋ชจ๋ธ (๋น ๋ฅธ ์ฒ๋ฆฌ + ๊ธฐ๋ณธ ํ์ง๊ฐ์ )" |
|
) |
|
|
|
aspect_ratio = gr.Dropdown( |
|
label="์ข
ํก๋น", |
|
choices=["1:1", "3:2", "2:3"], |
|
value="1:1" |
|
) |
|
|
|
output_format = gr.Dropdown( |
|
label="์ด๋ฏธ์ง ํ์", |
|
choices=["jpg", "png"], |
|
value="jpg" |
|
) |
|
|
|
|
|
enable_enhancement = gr.Checkbox( |
|
label="์ถ๊ฐ ํ์ง ๊ฐ์ ", |
|
value=False, |
|
info="GPT: 1ํ ํ์ง๊ฐ์ , Flux: 2์ฐจ ํ์ง๊ฐ์ (๊ธฐ๋ณธ 1ํ + ์ถ๊ฐ 1ํ)" |
|
) |
|
enhancement_level = gr.Slider(label="ํ์ง ๊ฐ์ ๋ ๋ฒจ", minimum=1, maximum=4, value=2, step=1, visible=False) |
|
|
|
|
|
generate_prompt_btn = gr.Button("ํ๋กฌํํธ๋ง ์์ฑ") |
|
|
|
|
|
edit_btn = gr.Button("์ด๋ฏธ์ง ํธ์ง ๋ฐ ํ์ง ๊ฐ์ ") |
|
|
|
with gr.Column(): |
|
with gr.Row(): |
|
with gr.Column(): |
|
gr.Markdown("## ํธ์ง๋ ์ด๋ฏธ์ง") |
|
original_output = gr.Gallery(label="ํธ์ง ๊ฒฐ๊ณผ", preview=True) |
|
original_download = gr.File(label="ํธ์ง ์ด๋ฏธ์ง ๋ค์ด๋ก๋", interactive=False) |
|
|
|
with gr.Column(): |
|
gr.Markdown("## ํ์ง ๊ฐ์ ๋ ์ด๋ฏธ์ง") |
|
enhanced_output = gr.Gallery(label="ํ์ง ๊ฐ์ ๊ฒฐ๊ณผ", preview=True) |
|
enhanced_download = gr.File(label="๊ฐ์ ์ด๋ฏธ์ง ๋ค์ด๋ก๋", interactive=False) |
|
|
|
|
|
prompt_output = gr.Textbox(label="์์ฑ๋ ํ๋กฌํํธ", lines=10, interactive=False) |
|
info = gr.Textbox(label="์ฒ๋ฆฌ ์ ๋ณด", interactive=False) |
|
error = gr.Textbox(label="์ค๋ฅ ๋ฉ์์ง", interactive=False, visible=True) |
|
|
|
|
|
def generate_prompt_with_password_check(password, bg_type, simple, studio, nature, indoor, special, jewelry, special_effects, request_text, aspect_ratio): |
|
try: |
|
return api_client.predict( |
|
password=password, |
|
bg_type=bg_type, |
|
simple=simple, |
|
studio=studio, |
|
nature=nature, |
|
indoor=indoor, |
|
special=special, |
|
jewelry=jewelry, |
|
special_effects=special_effects, |
|
request_text=request_text, |
|
aspect_ratio=aspect_ratio, |
|
api_name="/generate_prompt_with_password_check" |
|
) |
|
except Exception as e: |
|
return f"API ํธ์ถ ์ค๋ฅ: {str(e)}" |
|
|
|
|
|
def check_password(password, *args): |
|
try: |
|
image, bg_type, simple, studio, nature, indoor, special, jewelry, special_effects, request_text, quality_level, aspect_ratio, output_format, enable_enhancement = args |
|
|
|
if image is None: |
|
return ([], None, [], None, "", "", "์ด๋ฏธ์ง๋ฅผ ์
๋ก๋ํด์ผ ํฉ๋๋ค.") |
|
|
|
|
|
temp_path = save_uploaded_file(image) |
|
if temp_path is None: |
|
return ([], None, [], None, "", "", "์ด๋ฏธ์ง ์ฒ๋ฆฌ์ ์คํจํ์ต๋๋ค.") |
|
|
|
try: |
|
|
|
result = api_client.predict( |
|
password=password, |
|
param_1=handle_file(temp_path), |
|
param_2=bg_type, |
|
param_3=simple, |
|
param_4=studio, |
|
param_5=nature, |
|
param_6=indoor, |
|
param_7=special, |
|
param_8=jewelry, |
|
param_9=special_effects, |
|
param_10=request_text, |
|
param_11=quality_level, |
|
param_12=aspect_ratio, |
|
param_13=output_format, |
|
param_14=enable_enhancement, |
|
api_name="/check_password" |
|
) |
|
|
|
|
|
if result and len(result) >= 7: |
|
original_output, original_download, enhanced_output, enhanced_download, prompt_output, info, error = result |
|
|
|
|
|
logger.info(f"Original output type: {type(original_output)}") |
|
logger.info(f"Enhanced output type: {type(enhanced_output)}") |
|
if original_output: |
|
logger.info(f"Original output first item: {type(original_output[0]) if original_output else 'Empty'}") |
|
if original_output and isinstance(original_output[0], dict): |
|
logger.info(f"Original output keys: {list(original_output[0].keys())}") |
|
|
|
|
|
def convert_gallery_to_images(gallery_data): |
|
if not gallery_data: |
|
return [] |
|
|
|
images = [] |
|
logger.info(f"Converting gallery data, length: {len(gallery_data)}") |
|
|
|
for i, item in enumerate(gallery_data): |
|
try: |
|
logger.info(f"Processing gallery item {i}: {type(item)}") |
|
|
|
img_url = None |
|
if isinstance(item, dict): |
|
|
|
if 'image' in item: |
|
if isinstance(item['image'], dict): |
|
img_url = item['image'].get('url') or item['image'].get('path') |
|
else: |
|
img_url = item['image'] |
|
elif 'url' in item: |
|
img_url = item['url'] |
|
elif 'path' in item: |
|
img_url = item['path'] |
|
|
|
logger.info(f"Extracted URL from dict: {img_url}") |
|
elif isinstance(item, str): |
|
|
|
img_url = item |
|
logger.info(f"Direct URL: {img_url}") |
|
|
|
if img_url: |
|
|
|
if img_url.startswith('/'): |
|
img_url = f"https://happydoggg-49493h.hf.space/gradio_api/file={img_url}" |
|
elif not img_url.startswith('http'): |
|
img_url = f"https://happydoggg-49493h.hf.space/gradio_api/file={img_url}" |
|
|
|
logger.info(f"Final URL: {img_url}") |
|
|
|
|
|
response = requests.get(img_url) |
|
if response.status_code == 200: |
|
pil_image = Image.open(io.BytesIO(response.content)) |
|
images.append(pil_image) |
|
logger.info(f"Successfully converted image {i}") |
|
else: |
|
logger.warning(f"Failed to download image from {img_url}, status: {response.status_code}") |
|
else: |
|
logger.warning(f"No URL found in item {i}: {item}") |
|
|
|
except Exception as e: |
|
logger.error(f"Failed to convert gallery item {i}: {e}") |
|
logger.error(f"Item content: {item}") |
|
continue |
|
|
|
logger.info(f"Converted {len(images)} images from gallery data") |
|
return images |
|
|
|
|
|
converted_original = convert_gallery_to_images(original_output) |
|
converted_enhanced = convert_gallery_to_images(enhanced_output) |
|
|
|
|
|
if not converted_original and original_output: |
|
logger.info("No converted original images, trying to use original data directly") |
|
converted_original = original_output |
|
|
|
if not converted_enhanced and enhanced_output: |
|
logger.info("No converted enhanced images, trying to use enhanced data directly") |
|
converted_enhanced = enhanced_output |
|
|
|
|
|
original_file = None |
|
enhanced_file = None |
|
|
|
|
|
if converted_original: |
|
try: |
|
original_file_path = f"original_image.{output_format}" |
|
converted_original[0].save(original_file_path, format=output_format.upper()) |
|
original_file = original_file_path |
|
except Exception as e: |
|
logger.error(f"Error saving original image: {e}") |
|
|
|
|
|
if converted_enhanced: |
|
try: |
|
enhanced_file_path = f"enhanced_image.{output_format}" |
|
converted_enhanced[0].save(enhanced_file_path, format=output_format.upper()) |
|
enhanced_file = enhanced_file_path |
|
except Exception as e: |
|
logger.error(f"Error saving enhanced image: {e}") |
|
|
|
return ( |
|
converted_original, |
|
original_file, |
|
converted_enhanced, |
|
enhanced_file, |
|
prompt_output, |
|
info, |
|
error |
|
) |
|
else: |
|
return ([], None, [], None, "", "", "API ์๋ต์ด ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค.") |
|
|
|
finally: |
|
|
|
if os.path.exists(temp_path): |
|
try: |
|
os.remove(temp_path) |
|
except: |
|
pass |
|
|
|
except Exception as e: |
|
logger.error(f"Error in check_password: {e}") |
|
logger.error(f"Full traceback: {traceback.format_exc()}") |
|
return ([], None, [], None, "", "", f"์ค๋ฅ ๋ฐ์: {str(e)}") |
|
|
|
|
|
generate_prompt_btn.click( |
|
fn=generate_prompt_with_password_check, |
|
inputs=[ |
|
password_box, |
|
background_type, |
|
simple_dropdown, studio_dropdown, nature_dropdown, indoor_dropdown, special_dropdown, |
|
jewelry_dropdown, special_effects_dropdown, |
|
request_text, aspect_ratio |
|
], |
|
outputs=[prompt_output], |
|
api_name="generate_prompt_with_password_check" |
|
) |
|
|
|
|
|
edit_btn.click( |
|
fn=check_password, |
|
inputs=[ |
|
password_box, |
|
image, background_type, |
|
simple_dropdown, studio_dropdown, nature_dropdown, indoor_dropdown, special_dropdown, |
|
jewelry_dropdown, special_effects_dropdown, |
|
request_text, quality_level, aspect_ratio, output_format, enable_enhancement |
|
], |
|
outputs=[ |
|
original_output, original_download, |
|
enhanced_output, enhanced_download, |
|
prompt_output, info, error |
|
], |
|
api_name="check_password" |
|
) |
|
|
|
logger.info("Gradio interface created successfully") |
|
return app |
|
except Exception as e: |
|
logger.error(f"Error creating Gradio interface: {e}") |
|
logger.error(traceback.format_exc()) |
|
raise |
|
|
|
|
|
if __name__ == "__main__": |
|
try: |
|
logger.info("Starting application") |
|
|
|
|
|
os.makedirs("imgs", exist_ok=True) |
|
logger.info("์ด๋ฏธ์ง ๋๋ ํ ๋ฆฌ ์ค๋น ์๋ฃ") |
|
|
|
app = create_gradio_interface() |
|
logger.info("Launching Gradio app") |
|
app.launch(share=True) |
|
except Exception as e: |
|
logger.error(f"Error running app: {e}") |
|
logger.error(traceback.format_exc()) |