Up_G / app.py
ssboost's picture
Update app.py
29f2cfb verified
import os
import logging
import replicate
import gradio as gr
from PIL import Image
import tempfile
import uuid
# ๋กœ๊น… ์„ค์ •
logger = logging.getLogger(__name__)
# ํ™˜๊ฒฝ๋ณ€์ˆ˜์—์„œ ์„ค์ •๊ฐ’๋“ค ๊ฐ€์ ธ์˜ค๊ธฐ
REPLICATE_API_TOKEN = os.environ.get("REPLICATE_API_TOKEN", "")
APP_PASSWORD = os.environ.get("APP_PASSWORD", "")
REPLICATE_MODEL = os.environ.get("REPLICATE_MODEL", "")
# ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ฒ€์ฆ
if not REPLICATE_API_TOKEN:
logger.warning("REPLICATE_API_TOKEN์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์ฃผ์„ธ์š”.")
if not APP_PASSWORD:
logger.warning("APP_PASSWORD๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์ฃผ์„ธ์š”.")
if not REPLICATE_MODEL:
logger.warning("REPLICATE_MODEL์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์ฃผ์„ธ์š”.")
# ์ž„์‹œ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ
TEMP_DIR = os.path.join(tempfile.gettempdir(), "image_processor")
os.makedirs(TEMP_DIR, exist_ok=True)
logger.info(f"์ž„์‹œ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ: {TEMP_DIR}")
def upscale_image(
image,
scale_factor=2,
output_format="jpg",
sd_model="juggernaut_reborn.safetensors [338b85bc4f]",
resemblance=0.6,
creativity=0.35,
prompt="masterpiece, best quality, highres, <lora:more_details:0.5> <lora:SDXLrender_v2.0:1>",
negative_prompt="(worst quality, low quality, normal quality:2) JuggernautNegative-neg",
seed=1337,
dynamic=6,
sharpen=0
):
"""
Clarity Upscaler๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ํ™”์งˆ์„ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค.
Args:
image: ์ž…๋ ฅ ์ด๋ฏธ์ง€
scale_factor: ํ™•๋Œ€ ๋น„์œจ (๊ธฐ๋ณธ๊ฐ’: 2)
output_format: ์ถœ๋ ฅ ํ˜•์‹ (๊ธฐ๋ณธ๊ฐ’: jpg)
sd_model: ์‚ฌ์šฉํ•  SD ๋ชจ๋ธ
resemblance: ์›๋ณธ๊ณผ์˜ ์œ ์‚ฌ๋„ (0.0-1.0)
creativity: ์ฐฝ์˜์„ฑ ์ˆ˜์ค€ (0.0-1.0)
prompt: ์—…์Šค์ผ€์ผ๋ง ๊ฐ€์ด๋“œ ํ”„๋กฌํ”„ํŠธ
negative_prompt: ๋„ค๊ฑฐํ‹ฐ๋ธŒ ํ”„๋กฌํ”„ํŠธ
seed: ๋žœ๋ค ์‹œ๋“œ
dynamic: ๋‹ค์ด๋‚˜๋ฏน ์ž„๊ณ„๊ฐ’ (1-10)
sharpen: ์„ ๋ช…๋„ (0-2)
Returns:
๊ฐœ์„ ๋œ ์ด๋ฏธ์ง€
"""
if not REPLICATE_API_TOKEN:
raise ValueError("REPLICATE_API_TOKEN์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
if not REPLICATE_MODEL:
raise ValueError("REPLICATE_MODEL์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
try:
# ์ด๋ฏธ์ง€ ์ €์žฅ
temp_input_path = os.path.join(TEMP_DIR, f"input_{uuid.uuid4()}.png")
image.save(temp_input_path)
logger.info(f"์ž…๋ ฅ ์ด๋ฏธ์ง€ ์ €์žฅ: {temp_input_path}")
# Replicate ์„ค์ •
replicate.client.Client(api_token=REPLICATE_API_TOKEN)
# ๋กœ๊ทธ ์ •๋ณด ์ถœ๋ ฅ
logger.info(f"SD ๋ชจ๋ธ: {sd_model}")
logger.info(f"์Šค์ผ€์ผ ํŒฉํ„ฐ: {scale_factor}")
logger.info(f"์ถœ๋ ฅ ํ˜•์‹: {output_format}")
logger.info(f"์œ ์‚ฌ๋„: {resemblance}")
logger.info(f"์ฐฝ์˜์„ฑ: {creativity}")
logger.info(f"๋‹ค์ด๋‚˜๋ฏน: {dynamic}")
logger.info(f"์„ ๋ช…๋„: {sharpen}")
logger.info(f"์‹œ๋“œ: {seed}")
# ํ™˜๊ฒฝ๋ณ€์ˆ˜์—์„œ ๊ฐ€์ ธ์˜จ ๋ชจ๋ธ๋กœ API ํ˜ธ์ถœ
output = replicate.run(
REPLICATE_MODEL,
input={
"seed": seed,
"image": open(temp_input_path, "rb"),
"prompt": prompt,
"dynamic": dynamic,
"handfix": "disabled",
"pattern": False,
"sharpen": sharpen,
"sd_model": sd_model,
"scheduler": "DPM++ 3M SDE Karras",
"creativity": creativity,
"lora_links": "",
"downscaling": False,
"resemblance": resemblance,
"scale_factor": scale_factor,
"tiling_width": 112,
"output_format": output_format,
"tiling_height": 144,
"custom_sd_model": "",
"negative_prompt": negative_prompt,
"num_inference_steps": 18,
"downscaling_resolution": 768
}
)
logger.info(f"Replicate API ์‘๋‹ต: {output}")
# ๊ฒฐ๊ณผ ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ ๋ฐ ๋ฐ˜ํ™˜
if output and isinstance(output, list) and len(output) > 0:
import requests
from io import BytesIO
response = requests.get(output[0])
if response.status_code == 200:
result_image = Image.open(BytesIO(response.content))
# JPG๋กœ ๋ณ€ํ™˜ (output_format์ด jpg์ธ ๊ฒฝ์šฐ)
if output_format.lower() == "jpg":
temp_output = BytesIO()
if result_image.mode == 'RGBA':
result_image = result_image.convert('RGB')
result_image.save(temp_output, format='JPEG', quality=95)
temp_output.seek(0)
result_image = Image.open(temp_output)
logger.info("์ด๋ฏธ์ง€ ํ™”์งˆ ๊ฐœ์„  ์™„๋ฃŒ!")
return result_image
else:
logger.error(f"๊ฒฐ๊ณผ ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ ์‹คํŒจ: {response.status_code}")
return None
else:
logger.error("API ์‘๋‹ต์—์„œ ์ด๋ฏธ์ง€๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
return None
except Exception as e:
logger.error(f"ํ™”์งˆ ๊ฐœ์„  ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
raise
finally:
# ์ž„์‹œ ํŒŒ์ผ ์ •๋ฆฌ
if os.path.exists(temp_input_path):
os.remove(temp_input_path)
def process_and_download(
password, image, scale_factor, output_format, sd_model,
resemblance, creativity, dynamic, sharpen, seed
):
# ํ™˜๊ฒฝ๋ณ€์ˆ˜์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ฒ€์ฆ
if not APP_PASSWORD:
raise ValueError("์„œ๋ฒ„ ์„ค์ • ์˜ค๋ฅ˜์ž…๋‹ˆ๋‹ค. APP_PASSWORD๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
if password != APP_PASSWORD:
raise ValueError("์ž˜๋ชป๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ์ž…๋‹ˆ๋‹ค.")
if image is None:
return None, None
# ์ด๋ฏธ์ง€ ์—…์Šค์ผ€์ผ
result_img = upscale_image(
image=image,
scale_factor=scale_factor,
output_format=output_format,
sd_model=sd_model,
resemblance=resemblance,
creativity=creativity,
dynamic=dynamic,
sharpen=sharpen,
seed=int(seed)
)
if result_img is None:
return None, None
# ํŒŒ์ผ๋กœ ์ €์žฅ
ext = "jpg" if output_format.lower() == "jpg" else "png"
# JPG๋กœ ์ €์žฅํ•  ๋• RGB ๋ชจ๋“œ๋กœ ๋ณ€ํ™˜
if ext == "jpg" and result_img.mode == "RGBA":
result_img = result_img.convert("RGB")
filename = f"upscaled_{uuid.uuid4()}.{ext}"
filepath = os.path.join(TEMP_DIR, filename)
result_img.save(filepath, format="JPEG" if ext=="jpg" else "PNG")
# ๋ฆฌํ„ด: (์ด๋ฏธ์ง€, ํŒŒ์ผ ๊ฒฝ๋กœ)
return result_img, filepath
def create_interface():
with gr.Blocks(title="Clarity Upscaler") as demo:
with gr.Row():
with gr.Column():
password_input = gr.Textbox(
label="๋น„๋ฐ€๋ฒˆํ˜ธ", type="password", placeholder="๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”"
)
input_image = gr.Image(label="์›๋ณธ ์ด๋ฏธ์ง€", type="pil")
with gr.Accordion("๊ณ ๊ธ‰ ์„ค์ •", open=False):
scale_factor = gr.Slider(1, 4, value=2, step=0.5, label="ํ™•๋Œ€ ๋น„์œจ")
output_format = gr.Radio(["jpg","png"], value="jpg", label="์ถœ๋ ฅ ํ˜•์‹")
sd_model = gr.Dropdown(
choices=[
"juggernaut_reborn.safetensors [338b85bc4f]",
"sd_xl_base_1.0.safetensors [39d4e625d]",
"sdxl_base_v0.9-9961.safetensors [3048045c]",
"realisticVisionV51_v51VAE.safetensors [5ecbfa0ac]",
],
value="juggernaut_reborn.safetensors [338b85bc4f]",
label="SD ๋ชจ๋ธ"
)
resemblance = gr.Slider(0.0,1.0, value=0.6, step=0.05, label="์›๋ณธ ์œ ์‚ฌ๋„")
creativity = gr.Slider(0.0,1.0, value=0.35,step=0.05, label="์ฐฝ์˜์„ฑ")
dynamic = gr.Slider(1,10, value=6, step=1, label="๋‹ค์ด๋‚˜๋ฏน ์ž„๊ณ„๊ฐ’")
sharpen = gr.Slider(0,2, value=0, step=0.1, label="์„ ๋ช…๋„")
seed = gr.Number(value=1337, label="์‹œ๋“œ", precision=0)
submit_btn = gr.Button("์‹คํ–‰", variant="primary")
with gr.Column():
output_image = gr.Image(label="๊ฐœ์„ ๋œ ์ด๋ฏธ์ง€")
download_btn = gr.DownloadButton(label="์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ")
# ํด๋ฆญ ์‹œ ๋‘ ๊ฐœ์˜ ์ถœ๋ ฅ(์ด๋ฏธ์ง€, ํŒŒ์ผ ๊ฒฝ๋กœ)์„ ๋ฐ˜ํ™˜
submit_btn.click(
fn=process_and_download,
inputs=[
password_input,
input_image, scale_factor, output_format, sd_model,
resemblance, creativity, dynamic, sharpen, seed
],
outputs=[output_image, download_btn]
)
return demo
if __name__ == "__main__":
demo = create_interface()
demo.launch(share=True)