Image_Filter-1 / app.py
ssboost's picture
Update app.py
b7d35a7 verified
raw
history blame
19.4 kB
import cv2
import numpy as np
from PIL import Image, ImageEnhance, ImageFilter
import gradio as gr
from io import BytesIO
import tempfile
import logging
import replicate
import requests
import os
from dotenv import load_dotenv
import base64
from datetime import datetime, timedelta
import uuid
import time
# .env ํŒŒ์ผ์—์„œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๋กœ๋“œ (์—†์œผ๋ฉด ๋ฌด์‹œ)
load_dotenv()
# ๋กœ๊น… ์„ค์ • - INFO ๋ ˆ๋ฒจ๋กœ ๋ณ€๊ฒฝ
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Replicate API ํ† ํฐ ์„ค์ •
REPLICATE_API_TOKEN = os.getenv("REPLICATE_API_TOKEN", "์—ฌ๊ธฐ์—_API_ํ† ํฐ์„_์ž…๋ ฅํ•˜์„ธ์š”")
os.environ["REPLICATE_API_TOKEN"] = REPLICATE_API_TOKEN
# ์„ธ์…˜๋ณ„ ์ด๋ฏธ์ง€ ์ €์žฅ์šฉ ๋”•์…”๋„ˆ๋ฆฌ
session_images = {}
def adjust_brightness(image, value):
"""์ด๋ฏธ์ง€ ๋ฐ๊ธฐ ์กฐ์ ˆ"""
value = float(value - 1) * 100 # 0-2 ๋ฒ”์œ„๋ฅผ -100์—์„œ +100์œผ๋กœ ๋ณ€ํ™˜
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
v = cv2.add(v, value)
v = np.clip(v, 0, 255)
final_hsv = cv2.merge((h, s, v))
return cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR)
def adjust_contrast(image, value):
"""์ด๋ฏธ์ง€ ๋Œ€๋น„ ์กฐ์ ˆ"""
value = float(value)
return np.clip(image * value, 0, 255).astype(np.uint8)
def adjust_saturation(image, value):
"""์ด๋ฏธ์ง€ ์ฑ„๋„ ์กฐ์ ˆ"""
value = float(value - 1) * 100 # 0-2 ๋ฒ”์œ„๋ฅผ -100์—์„œ +100์œผ๋กœ ๋ณ€ํ™˜
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
s = cv2.add(s, value)
s = np.clip(s, 0, 255)
final_hsv = cv2.merge((h, s, v))
return cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR)
def adjust_temperature(image, value):
"""์ด๋ฏธ์ง€ ์ƒ‰์˜จ๋„ ์กฐ์ ˆ (์ƒ‰์ƒ ๋ฐธ๋Ÿฐ์Šค)"""
value = float(value) * 30 # ํšจ๊ณผ ์Šค์ผ€์ผ ์กฐ์ ˆ
b, g, r = cv2.split(image)
if value > 0: # ๋”ฐ๋œปํ•˜๊ฒŒ
r = cv2.add(r, value)
b = cv2.subtract(b, value)
else: # ์ฐจ๊ฐ‘๊ฒŒ
r = cv2.add(r, value)
b = cv2.subtract(b, value)
r = np.clip(r, 0, 255)
b = np.clip(b, 0, 255)
return cv2.merge([b, g, r])
def remove_background(image, session_id):
"""๋ฐฐ๊ฒฝ ์ œ๊ฑฐ ๊ธฐ๋Šฅ - Replicate API ์‚ฌ์šฉ"""
logger.info(f"์„ธ์…˜ {session_id}: ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ ์‹œ์ž‘")
# ์ž„์‹œ ํŒŒ์ผ๋กœ ์ด๋ฏธ์ง€ ์ €์žฅ
temp_file = tempfile.NamedTemporaryFile(suffix='.png', delete=False)
temp_file_path = temp_file.name
temp_file.close()
# PIL ์ด๋ฏธ์ง€๋ฅผ ์ž„์‹œ ํŒŒ์ผ๋กœ ์ €์žฅ
image.save(temp_file_path, format="PNG")
try:
# Replicate API๋กœ ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ ์š”์ฒญ
output = replicate.run(
"851-labs/background-remover:a029dff38972b5fda4ec5d75d7d1cd25aeff621d2cf4946a41055d7db66b80bc",
input={
"image": open(temp_file_path, "rb"),
"format": "png",
"reverse": False,
"threshold": 0,
"background_type": "rgba"
}
)
# URL์—์„œ ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ
response = requests.get(output)
if response.status_code == 200:
# ๋ฐ”์ดํŠธ ๋ฐ์ดํ„ฐ๋ฅผ PIL ์ด๋ฏธ์ง€๋กœ ๋ณ€ํ™˜
img = Image.open(BytesIO(response.content))
# PNG ํŒŒ์ผ๋กœ ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ๋œ ์ด๋ฏธ์ง€ ์ €์žฅ (๋งˆ์Šคํฌ์šฉ)
timestamp = get_korean_timestamp()
bg_removed_path = tempfile.gettempdir() + f"/bg_removed_{session_id}_{timestamp}.png"
img.save(bg_removed_path, format="PNG")
logger.info(f"์„ธ์…˜ {session_id}: ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ ์™„๋ฃŒ: {bg_removed_path}")
# ์„ธ์…˜ ์ •๋ณด ์ €์žฅ
session_images[session_id]['bg_removed_image'] = img
session_images[session_id]['bg_removed_path'] = bg_removed_path
return img
else:
logger.error(f"์„ธ์…˜ {session_id}: API ์‘๋‹ต ์˜ค๋ฅ˜: {response.status_code}")
return image
except Exception as e:
logger.error(f"์„ธ์…˜ {session_id}: ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ ์˜ค๋ฅ˜: {e}")
return image
finally:
# ์ž„์‹œ ํŒŒ์ผ ์‚ญ์ œ
if os.path.exists(temp_file_path):
os.unlink(temp_file_path)
def get_korean_timestamp():
"""ํ•œ๊ตญ ์‹œ๊ฐ„ ํƒ€์ž„์Šคํƒฌํ”„ ์ƒ์„ฑ"""
korea_time = datetime.utcnow() + timedelta(hours=9)
return korea_time.strftime('%Y%m%d_%H%M%S')
def handle_upload(image, session_id=None):
"""์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์ฒ˜๋ฆฌ ๋ฐ ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ"""
if image is None:
return None
# ์„ธ์…˜ ID ์ƒ์„ฑ ๋˜๋Š” ํ™•์ธ
if session_id is None or session_id not in session_images:
session_id = str(uuid.uuid4())
session_images[session_id] = {}
# ์›๋ณธ ์ด๋ฏธ์ง€ ์ €์žฅ
original_image = Image.fromarray(np.array(image))
session_images[session_id]['original_image'] = original_image
# ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ ์‹คํ–‰
bg_removed_image = remove_background(original_image, session_id)
# ํ•„ํ„ฐ ์ ์šฉ ์ „ ๊ธฐ๋ณธ ์ด๋ฏธ์ง€ ๋ฐ˜ํ™˜ (ํ•„ํ„ฐ ์—†์ด ์›๋ณธ ์ด๋ฏธ์ง€)
return original_image, session_id
def process_image(session_id, temperature, brightness, contrast, saturation, filter_mode):
"""๋ชจ๋“œ์— ๋”ฐ๋ฅธ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ"""
if session_id is None or session_id not in session_images:
logger.warning(f"์„ธ์…˜ ID๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค: {session_id}")
return None
original_image = session_images[session_id].get('original_image')
bg_removed_image = session_images[session_id].get('bg_removed_image')
if original_image is None:
return None
if bg_removed_image is None:
logger.warning(f"์„ธ์…˜ {session_id}: ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ๋œ ์ด๋ฏธ์ง€๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ „์ฒด ํ•„ํ„ฐ ๋ชจ๋“œ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.")
# ์ „์ฒด ํ•„ํ„ฐ๋กœ ์ฒ˜๋ฆฌ
cv_image = cv2.cvtColor(np.array(original_image), cv2.COLOR_RGB2BGR)
cv_image = adjust_temperature(cv_image, temperature)
cv_image = adjust_brightness(cv_image, brightness)
cv_image = adjust_contrast(cv_image, contrast)
cv_image = adjust_saturation(cv_image, saturation)
return Image.fromarray(cv2.cvtColor(cv_image, cv2.COLOR_BGR2RGB))
# ํ•„ํ„ฐ ๋ชจ๋“œ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์ฒ˜๋ฆฌ
if filter_mode == "์ „์ฒด ํ•„ํ„ฐ":
# ์›๋ณธ ์ด๋ฏธ์ง€์— ํ•„ํ„ฐ ์ ์šฉ
cv_image = cv2.cvtColor(np.array(original_image), cv2.COLOR_RGB2BGR)
cv_image = adjust_temperature(cv_image, temperature)
cv_image = adjust_brightness(cv_image, brightness)
cv_image = adjust_contrast(cv_image, contrast)
cv_image = adjust_saturation(cv_image, saturation)
return Image.fromarray(cv2.cvtColor(cv_image, cv2.COLOR_BGR2RGB))
elif filter_mode == "๋ฐฐ๊ฒฝ๋งŒ ํ•„ํ„ฐ ์ ์šฉ":
# ์›๋ณธ์— ํ•„ํ„ฐ ์ ์šฉ ํ›„ ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ๋œ ์ด๋ฏธ์ง€ ํ•ฉ์„ฑ
cv_image = cv2.cvtColor(np.array(original_image), cv2.COLOR_RGB2BGR)
cv_image = adjust_temperature(cv_image, temperature)
cv_image = adjust_brightness(cv_image, brightness)
cv_image = adjust_contrast(cv_image, contrast)
cv_image = adjust_saturation(cv_image, saturation)
filtered_original = Image.fromarray(cv2.cvtColor(cv_image, cv2.COLOR_BGR2RGB))
# ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ๋œ ์ด๋ฏธ์ง€๊ฐ€ RGBA ๋ชจ๋“œ์ธ์ง€ ํ™•์ธ
if bg_removed_image.mode != 'RGBA':
logger.warning(f"์„ธ์…˜ {session_id}: ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ๋œ ์ด๋ฏธ์ง€๊ฐ€ RGBA ๋ชจ๋“œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.")
return filtered_original
# ํ•„ํ„ฐ๋ง๋œ ์ด๋ฏธ์ง€๋ฅผ RGBA๋กœ ๋ณ€ํ™˜ (์•ŒํŒŒ ์ฑ„๋„ ์ถ”๊ฐ€)
if filtered_original.mode != 'RGBA':
filtered_original = filtered_original.convert('RGBA')
# ํ•ฉ์„ฑ (๋ฐฐ๊ฒฝ ์ œ๊ฑฐ๋œ ์ด๋ฏธ์ง€๋ฅผ ํ•„ํ„ฐ๋ง๋œ ์›๋ณธ ์œ„์— ๋ฐฐ์น˜)
result = Image.new('RGBA', filtered_original.size, (0, 0, 0, 0))
result.paste(filtered_original, (0, 0), None)
result.paste(bg_removed_image, (0, 0), bg_removed_image)
return result.convert('RGB')
elif filter_mode == "์ƒํ’ˆ๋งŒ ํ•„ํ„ฐ ์ ์šฉ":
# ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ๋œ ์ด๋ฏธ์ง€๋งŒ ํ•„ํ„ฐ ์ ์šฉ
cv_image = cv2.cvtColor(np.array(bg_removed_image), cv2.COLOR_RGBA2BGRA)
# ์•ŒํŒŒ ์ฑ„๋„ ๋ถ„๋ฆฌ
b, g, r, a = cv2.split(cv_image)
# BGR ์ด๋ฏธ์ง€๋กœ ํ•ฉ์น˜๊ธฐ
bgr = cv2.merge([b, g, r])
# ํ•„ํ„ฐ ์ ์šฉ
bgr = adjust_temperature(bgr, temperature)
bgr = adjust_brightness(bgr, brightness)
bgr = adjust_contrast(bgr, contrast)
bgr = adjust_saturation(bgr, saturation)
# ๋‹ค์‹œ ์•ŒํŒŒ ์ฑ„๋„๊ณผ ํ•ฉ์น˜๊ธฐ
filtered_bgra = cv2.merge([bgr[:,:,0], bgr[:,:,1], bgr[:,:,2], a])
filtered_bg_removed = Image.fromarray(cv2.cvtColor(filtered_bgra, cv2.COLOR_BGRA2RGBA))
# ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ๋œ ์ด๋ฏธ์ง€๊ฐ€ RGBA ๋ชจ๋“œ์ธ์ง€ ํ™•์ธ
if bg_removed_image.mode != 'RGBA':
logger.warning(f"์„ธ์…˜ {session_id}: ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ๋œ ์ด๋ฏธ์ง€๊ฐ€ RGBA ๋ชจ๋“œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.")
# ํ•„ํ„ฐ๋งŒ ์ ์šฉํ•˜๊ณ  ๋ฐ˜ํ™˜
return filtered_bg_removed
# ์›๋ณธ ์ด๋ฏธ์ง€๋ฅผ RGBA๋กœ ๋ณ€ํ™˜
original_rgba = original_image.convert('RGBA')
# ์›๋ณธ ์ด๋ฏธ์ง€์™€ ํ•„ํ„ฐ๋ง๋œ ๋ฐฐ๊ฒฝ ์ œ๊ฑฐ ์ด๋ฏธ์ง€๋ฅผ ํ•ฉ์„ฑ
result = Image.new('RGBA', original_rgba.size, (0, 0, 0, 0))
result.paste(original_rgba, (0, 0), None)
result.paste(filtered_bg_removed, (0, 0), bg_removed_image)
return result.convert('RGB')
# ๊ธฐ๋ณธ๊ฐ’์€ ์ „์ฒด ํ•„ํ„ฐ
cv_image = cv2.cvtColor(np.array(original_image), cv2.COLOR_RGB2BGR)
cv_image = adjust_temperature(cv_image, temperature)
cv_image = adjust_brightness(cv_image, brightness)
cv_image = adjust_contrast(cv_image, contrast)
cv_image = adjust_saturation(cv_image, saturation)
return Image.fromarray(cv2.cvtColor(cv_image, cv2.COLOR_BGR2RGB))
def download_image(image, session_id, format_type):
"""์ด๋ฏธ์ง€๋ฅผ ์ง€์ •๋œ ํ˜•์‹์œผ๋กœ ์ €์žฅํ•˜๊ณ  ๊ฒฝ๋กœ ๋ฐ˜ํ™˜"""
if image is None or session_id is None or session_id not in session_images:
return None
timestamp = get_korean_timestamp()
# ์›๋ณธ ํŒŒ์ผ๋ช… ๊ฐ€์ ธ์˜ค๊ธฐ (์žˆ๋Š” ๊ฒฝ์šฐ)
original_name = "์ด๋ฏธ์ง€"
if 'original_name' in session_images[session_id]:
original_name = session_images[session_id]['original_name']
if format_type == "JPG":
file_name = f"[๋์žฅAI]๋์žฅํ•„ํ„ฐ_{original_name}_{timestamp}.jpg"
format_str = "JPEG"
else: # PNG
file_name = f"[๋์žฅAI]๋์žฅํ•„ํ„ฐ_{original_name}_{timestamp}.png"
format_str = "PNG"
# ํŒŒ์ผ ์ €์žฅ
temp_file_path = tempfile.gettempdir() + "/" + file_name
image.save(temp_file_path, format=format_str)
return temp_file_path
def reset_filters(session_id):
"""ํ•„ํ„ฐ ์„ค์ • ์ดˆ๊ธฐํ™”"""
if session_id is None or session_id not in session_images:
return None, 0.0, 1.0, 1.0, 1.0
original_image = session_images[session_id].get('original_image')
return original_image, 0.0, 1.0, 1.0, 1.0
def create_interface():
css = """
footer {
visibility: hidden;
}
.download-button, .download-output, .reset-button {
width: 100%;
}
.download-container {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
#gradio-app {
margin: 0 !important;
text-align: left !important;
padding: 0 !important;
}
.gradio-container {
max-width: 100% !important;
margin: 0 !important;
padding: 0 !important;
}
.download-button, .reset-button {
background-color: black !important;
color: white !important;
border: none !important;
padding: 10px !important;
font-size: 16px !important;
border-radius: 4px !important;
}
.reset-button {
background-color: #666 !important;
}
.filter-mode {
margin-top: 20px;
margin-bottom: 20px;
}
.input-panel {
padding: 20px;
}
.output-panel {
padding: 20px;
height: 100%;
display: flex;
flex-direction: column;
}
.output-image {
flex-grow: 1;
min-height: 400px;
}
.filter-section {
margin: 15px 0;
padding: 15px;
border: 1px solid #eee;
border-radius: 8px;
}
.session-id {
display: none;
}
"""
with gr.Blocks(theme=gr.themes.Soft(
primary_hue=gr.themes.Color(
c50="#FFF7ED",
c100="#FFEDD5",
c200="#FED7AA",
c300="#FDBA74",
c400="#FB923C",
c500="#F97316",
c600="#EA580C",
c700="#C2410C",
c800="#9A3412",
c900="#7C2D12",
c950="#431407",
),
secondary_hue="zinc",
neutral_hue="zinc",
font=("Pretendard", "sans-serif")
), css=css) as interface:
# ์„ธ์…˜ ID (์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด์ง€ ์•Š์Œ)
session_id = gr.Textbox(visible=False, elem_classes="session-id")
with gr.Row():
# ์™ผ์ชฝ ์—ด: ์ž…๋ ฅ ํŒจ๋„
with gr.Column(scale=1, elem_classes="input-panel"):
# ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ
input_image = gr.Image(type="pil", label="์ด๋ฏธ์ง€ ์—…๋กœ๋“œ")
# ํ•„ํ„ฐ ๋ชจ๋“œ ์„ ํƒ
with gr.Group(elem_classes="filter-section"):
filter_mode = gr.Radio(
["์ „์ฒด ํ•„ํ„ฐ", "๋ฐฐ๊ฒฝ๋งŒ ํ•„ํ„ฐ ์ ์šฉ", "์ƒํ’ˆ๋งŒ ํ•„ํ„ฐ ์ ์šฉ"],
label="ํ•„ํ„ฐ ์ ์šฉ ๋ชจ๋“œ",
value="์ „์ฒด ํ•„ํ„ฐ",
elem_classes="filter-mode"
)
# ์กฐ์ • ์Šฌ๋ผ์ด๋” ๊ทธ๋ฃน (์ค‘์š” ์Šฌ๋ผ์ด๋”๋งŒ ๋‚จ๊น€)
with gr.Group(elem_classes="filter-section"):
gr.Markdown("### ์ด๋ฏธ์ง€ ํ•„ํ„ฐ ์„ค์ •")
# ์ƒ‰์˜จ๋„๋ฅผ ๊ฐ€์žฅ ์œ„๋กœ ๋ฐฐ์น˜
temperature_slider = gr.Slider(-1.0, 1.0, value=0.0, step=0.1, label="์ƒ‰์˜จ๋„ ์กฐ์ ˆ")
brightness_slider = gr.Slider(0.0, 2.0, value=1.0, step=0.1, label="๋ฐ๊ธฐ ์กฐ์ ˆ")
contrast_slider = gr.Slider(0.5, 1.5, value=1.0, step=0.1, label="๋Œ€๋น„ ์กฐ์ ˆ")
saturation_slider = gr.Slider(0.0, 2.0, value=1.0, step=0.1, label="์ฑ„๋„ ์กฐ์ ˆ")
# ๋ฆฌ์…‹ ๋ฒ„ํŠผ
reset_button = gr.Button("ํ•„ํ„ฐ ์ดˆ๊ธฐํ™”", elem_classes="reset-button")
# ์˜ค๋ฅธ์ชฝ ์—ด: ์ถœ๋ ฅ ํŒจ๋„
with gr.Column(scale=1, elem_classes="output-panel"):
# ํ•„ํ„ฐ ์ ์šฉ๋œ ์ด๋ฏธ์ง€ ์ถœ๋ ฅ
filtered_output = gr.Image(type="pil", label="ํ•„ํ„ฐ ์ ์šฉ๋œ ์ด๋ฏธ์ง€", elem_classes="output-image")
# ์ด๋ฏธ์ง€ ์ €์žฅ ์˜ต์…˜ ๋ฐ ๋‹ค์šด๋กœ๋“œ
with gr.Row():
with gr.Column(scale=1):
format_select = gr.Radio(
["JPG", "PNG"],
label="์ €์žฅ ํ˜•์‹",
value="JPG"
)
with gr.Column(scale=2):
download_button = gr.Button("์ด๋ฏธ์ง€ ๋ณ€ํ™˜ํ•˜๊ธฐ", elem_classes="download-button")
# ๋‹ค์šด๋กœ๋“œ ๋งํฌ
download_output = gr.File(label="๋ณ€ํ™˜๋œ ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ")
# ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์ฒ˜๋ฆฌ ๋ฐ ์ดˆ๊ธฐ ์ถœ๋ ฅ ์„ค์ •
def update_image_and_session(image):
if image is not None:
# ํŒŒ์ผ ์ด๋ฆ„ ์ €์žฅ (๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ)
original_name = "์ด๋ฏธ์ง€"
if hasattr(image, 'name'):
original_name = image.name.split('.')[0]
# ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ๋ฐ ์„ธ์…˜ ์ƒ์„ฑ
result_image, new_session_id = handle_upload(image)
# ์›๋ณธ ํŒŒ์ผ๋ช… ์ €์žฅ
if new_session_id in session_images:
session_images[new_session_id]['original_name'] = original_name
return result_image, new_session_id
return None, None
input_image.change(
fn=update_image_and_session,
inputs=[input_image],
outputs=[filtered_output, session_id]
)
# ํ•„ํ„ฐ ์ ์šฉ ํ•จ์ˆ˜
def apply_filters(session_id, temperature, brightness, contrast, saturation, filter_mode):
return process_image(session_id, temperature, brightness, contrast, saturation, filter_mode)
# ํ•„ํ„ฐ ์ž…๋ ฅ ๋ณ€๊ฒฝ ์‹œ ์ฒ˜๋ฆฌ
filter_inputs = [
session_id,
temperature_slider,
brightness_slider,
contrast_slider,
saturation_slider,
filter_mode
]
# ์Šฌ๋ผ์ด๋” ๋ณ€๊ฒฝ ์‹œ ์ฒ˜๋ฆฌ
for input_component in [temperature_slider, brightness_slider, contrast_slider, saturation_slider]:
input_component.change(
fn=apply_filters,
inputs=filter_inputs,
outputs=filtered_output
)
# ํ•„ํ„ฐ ๋ชจ๋“œ ๋ณ€๊ฒฝ ์‹œ ์ฒ˜๋ฆฌ
filter_mode.change(
fn=apply_filters,
inputs=filter_inputs,
outputs=filtered_output
)
# ๋ฆฌ์…‹ ๋ฒ„ํŠผ ๊ธฐ๋Šฅ
reset_button.click(
fn=reset_filters,
inputs=[session_id],
outputs=[filtered_output, temperature_slider, brightness_slider, contrast_slider, saturation_slider]
)
# ๋‹ค์šด๋กœ๋“œ ๋ฒ„ํŠผ ๊ธฐ๋Šฅ
download_button.click(
fn=download_image,
inputs=[filtered_output, session_id, format_select],
outputs=download_output
)
# ์„ธ์…˜ ์ •๋ฆฌ ํƒ€์ด๋จธ (30๋ถ„ ์ด์ƒ ๋œ ์„ธ์…˜ ์ œ๊ฑฐ)
def cleanup_sessions():
current_time = time.time()
to_remove = []
for sess_id in session_images:
if 'created_at' in session_images[sess_id]:
if current_time - session_images[sess_id]['created_at'] > 1800: # 30๋ถ„
to_remove.append(sess_id)
for sess_id in to_remove:
# ์ž„์‹œ ํŒŒ์ผ ์ œ๊ฑฐ
if 'bg_removed_path' in session_images[sess_id]:
path = session_images[sess_id]['bg_removed_path']
if os.path.exists(path):
os.unlink(path)
# ์„ธ์…˜ ์ •๋ณด ์ œ๊ฑฐ
del session_images[sess_id]
# 10๋ถ„๋งˆ๋‹ค ์‹คํ–‰
gr.set_interval(cleanup_sessions, 600)
# ์„ธ์…˜ ์ •๋ฆฌ ์‹œ์ž‘
interface.load(cleanup_sessions)
return interface
# ์ธํ„ฐํŽ˜์ด์Šค ์ƒ์„ฑ ๋ฐ ์‹คํ–‰
if __name__ == "__main__":
logger.info("์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘")
interface = create_interface()
interface.queue()
interface.launch()