Update app.py
Browse files
app.py
CHANGED
@@ -10,9 +10,8 @@ import numpy as np
|
|
10 |
from io import BytesIO
|
11 |
from datetime import datetime, timedelta
|
12 |
import random
|
13 |
-
import requests
|
14 |
-
import base64
|
15 |
from dotenv import load_dotenv
|
|
|
16 |
|
17 |
load_dotenv()
|
18 |
|
@@ -20,316 +19,177 @@ load_dotenv()
|
|
20 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
21 |
logger = logging.getLogger(__name__)
|
22 |
|
23 |
-
#
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
return None
|
31 |
-
|
32 |
-
# ํ๊น
ํ์ด์ค ์คํ์ด์ค ํ์ ์ฒ๋ฆฌ
|
33 |
-
if "/" in endpoint and not endpoint.startswith("http"):
|
34 |
-
# "username/spacename" ํ์์ ์ ์ฒด URL๋ก ๋ณํ
|
35 |
-
endpoint = f"https://{endpoint.replace('/', '-')}.hf.space"
|
36 |
-
elif not endpoint.startswith("http"):
|
37 |
-
# ๋จ์ ๋๋ฉ์ธ์ธ ๊ฒฝ์ฐ https ์ถ๊ฐ
|
38 |
-
endpoint = f"https://{endpoint}"
|
39 |
-
|
40 |
-
return endpoint
|
41 |
|
42 |
-
def
|
43 |
-
"""PIL
|
44 |
if image is None:
|
45 |
return None
|
46 |
|
47 |
-
buffered = BytesIO()
|
48 |
-
image.save(buffered, format="PNG")
|
49 |
-
img_str = base64.b64encode(buffered.getvalue()).decode()
|
50 |
-
return img_str
|
51 |
-
|
52 |
-
def decode_base64_to_image(base64_str):
|
53 |
-
"""base64 ๋ฌธ์์ด์ PIL ์ด๋ฏธ์ง๋ก ๋์ฝ๋ฉ"""
|
54 |
-
if not base64_str:
|
55 |
-
return None
|
56 |
-
|
57 |
-
image_data = base64.b64decode(base64_str)
|
58 |
-
image = Image.open(BytesIO(image_data))
|
59 |
-
return image
|
60 |
-
|
61 |
-
def call_api_endpoint(endpoint_url, data):
|
62 |
-
"""API ์๋ํฌ์ธํธ ํธ์ถ ํจ์"""
|
63 |
try:
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
#
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
# ํ๊น
ํ์ด์ค ์คํ์ด์ค ํ์ ์ฒ๋ฆฌ
|
82 |
-
if "/" in endpoint and not endpoint.startswith("http"):
|
83 |
-
# "username/spacename" ํ์์ ์ ์ฒด URL๋ก ๋ณํ
|
84 |
-
endpoint = f"https://{endpoint.replace('/', '-')}.hf.space"
|
85 |
-
elif not endpoint.startswith("http"):
|
86 |
-
# ๋จ์ ๋๋ฉ์ธ์ธ ๊ฒฝ์ฐ https ์ถ๊ฐ
|
87 |
-
endpoint = f"https://{endpoint}"
|
88 |
-
|
89 |
-
return endpoint
|
90 |
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
response = requests.post(endpoint_url, json=data, timeout=300)
|
95 |
-
response.raise_for_status()
|
96 |
-
return response.json()
|
97 |
-
except requests.exceptions.RequestException as e:
|
98 |
-
# ์๋ํฌ์ธํธ ์ ๋ณด๋ฅผ ์จ๊ธฐ๊ณ ์ผ๋ฐ์ ์ธ ์ค๋ฅ ๋ฉ์์ง๋ง ํ์
|
99 |
-
logger.error("API ํธ์ถ ์ค ์ค๋ฅ ๋ฐ์")
|
100 |
-
return {"error": "API ํธ์ถ ์คํจ"}
|
101 |
-
|
102 |
-
def translate_prompt_to_english(prompt):
|
103 |
-
"""ํ๋กฌํํธ ๋ฒ์ญ - API ์๋ํฌ์ธํธ๋ก ์ ๋ฌ"""
|
104 |
-
endpoint_url = get_api_endpoint()
|
105 |
-
if not endpoint_url:
|
106 |
-
return prompt
|
107 |
-
|
108 |
-
data = {
|
109 |
-
"function": "translate_prompt",
|
110 |
-
"prompt": prompt
|
111 |
-
}
|
112 |
-
|
113 |
try:
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
if
|
133 |
-
|
134 |
-
encoded_images.append(encoded_img)
|
135 |
else:
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
"
|
140 |
-
"
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
try:
|
146 |
-
|
147 |
-
|
148 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
|
150 |
-
|
151 |
-
|
152 |
-
generated_image = decode_base64_to_image(result["image"])
|
153 |
-
return generated_image, result.get("status", "์ด๋ฏธ์ง๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์์ฑ๋์์ต๋๋ค.")
|
154 |
else:
|
155 |
-
return None, "API
|
|
|
156 |
except Exception as e:
|
157 |
-
logger.error("์ด๋ฏธ์ง ์์ฑ
|
158 |
-
return None, "
|
159 |
-
"""ํ๋กฌํํธ ์ ์ฒ๋ฆฌ - ๊ธฐ์กด ๋ก์ง ์ ์ง"""
|
160 |
-
has_img1 = image1 is not None
|
161 |
-
has_img2 = image2 is not None
|
162 |
-
has_img3 = image3 is not None
|
163 |
-
|
164 |
-
if "#1" in prompt and not has_img1:
|
165 |
-
prompt = prompt.replace("#1", "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง(์์)")
|
166 |
-
else:
|
167 |
-
prompt = prompt.replace("#1", "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง")
|
168 |
-
|
169 |
-
if "#2" in prompt and not has_img2:
|
170 |
-
prompt = prompt.replace("#2", "๋ ๋ฒ์งธ ์ด๋ฏธ์ง(์์)")
|
171 |
-
else:
|
172 |
-
prompt = prompt.replace("#2", "๋ ๋ฒ์งธ ์ด๋ฏธ์ง")
|
173 |
-
|
174 |
-
if "#3" in prompt and not has_img3:
|
175 |
-
prompt = prompt.replace("#3", "์ธ ๋ฒ์งธ ์ด๋ฏธ์ง(์์)")
|
176 |
-
else:
|
177 |
-
prompt = prompt.replace("#3", "์ธ ๋ฒ์งธ ์ด๋ฏธ์ง")
|
178 |
-
|
179 |
-
if "1. ์ด๋ฏธ์ง ๋ณ๊ฒฝ" in prompt:
|
180 |
-
desc_match = re.search(r'#1์ "(.*?)"์ผ๋ก ๋ฐ๊ฟ๋ผ', prompt)
|
181 |
-
if desc_match:
|
182 |
-
description = desc_match.group(1)
|
183 |
-
prompt = f"์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง๋ฅผ {description}์ผ๋ก ๋ณ๊ฒฝํด์ฃผ์ธ์. ์๋ณธ ์ด๋ฏธ์ง์ ์ฃผ์ ๋ด์ฉ์ ์ ์งํ๋ ์๋ก์ด ์คํ์ผ๊ณผ ๋ถ์๊ธฐ๋ก ์ฌํด์ํด์ฃผ์ธ์."
|
184 |
-
else:
|
185 |
-
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง๋ฅผ ์ฐฝ์์ ์ผ๋ก ๋ณํํด์ฃผ์ธ์. ๋ ์์ํ๊ณ ์์ ์ ์ธ ๋ฒ์ ์ผ๋ก ๋ง๋ค์ด์ฃผ์ธ์."
|
186 |
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
prompt = f"์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์์ '{text_to_remove}' ํ
์คํธ๋ฅผ ์ฐพ์ ์์ฐ์ค๋ฝ๊ฒ ์ ๊ฑฐํด์ฃผ์ธ์. ํ
์คํธ๊ฐ ์๋ ๋ถ๋ถ์ ๋ฐฐ๊ฒฝ๊ณผ ์กฐํ๋กญ๊ฒ ์ฑ์์ฃผ์ธ์."
|
192 |
-
else:
|
193 |
-
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์์ ๋ชจ๋ ํ
์คํธ๋ฅผ ์ฐพ์ ์์ฐ์ค๋ฝ๊ฒ ์ ๊ฑฐํด์ฃผ์ธ์. ๊น๋ํ ์ด๋ฏธ์ง๋ก ๋ง๋ค์ด์ฃผ์ธ์."
|
194 |
|
195 |
-
|
196 |
-
|
|
|
197 |
|
198 |
-
|
199 |
-
|
|
|
200 |
|
201 |
-
|
202 |
-
|
|
|
203 |
|
204 |
-
|
205 |
-
|
|
|
206 |
|
207 |
-
def
|
208 |
-
"""
|
209 |
-
|
210 |
-
if not endpoint_url:
|
211 |
-
return None, "API ์๋ํฌ์ธํธ๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค."
|
212 |
-
|
213 |
-
# ์ด๋ฏธ์ง๋ค์ base64๋ก ์ธ์ฝ๋ฉ
|
214 |
-
encoded_images = []
|
215 |
-
for img in images:
|
216 |
-
if img is not None:
|
217 |
-
encoded_img = encode_image_to_base64(img)
|
218 |
-
encoded_images.append(encoded_img)
|
219 |
-
else:
|
220 |
-
encoded_images.append(None)
|
221 |
-
|
222 |
-
data = {
|
223 |
-
"function": "generate_with_images",
|
224 |
-
"prompt": prompt,
|
225 |
-
"images": encoded_images,
|
226 |
-
"variation_index": variation_index
|
227 |
-
}
|
228 |
-
|
229 |
-
try:
|
230 |
-
result = call_api_endpoint(f"{endpoint_url}/generate", data)
|
231 |
-
if "error" in result:
|
232 |
-
return None, result["error"]
|
233 |
-
|
234 |
-
# base64 ์ด๋ฏธ์ง๋ฅผ PIL ์ด๋ฏธ์ง๋ก ๋ณํ
|
235 |
-
if "image" in result:
|
236 |
-
generated_image = decode_base64_to_image(result["image"])
|
237 |
-
return generated_image, result.get("status", "์ด๋ฏธ์ง๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์์ฑ๋์์ต๋๋ค.")
|
238 |
-
else:
|
239 |
-
return None, "API์์ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ์ง ๋ชปํ์ต๋๋ค."
|
240 |
-
except Exception as e:
|
241 |
-
logger.error(f"์ด๋ฏธ์ง ์์ฑ API ํธ์ถ ์ค ์ค๋ฅ: {str(e)}")
|
242 |
-
return None, f"์ด๋ฏธ์ง ์์ฑ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}"
|
243 |
|
244 |
-
def
|
245 |
-
"""
|
246 |
-
|
247 |
-
last_error = None
|
248 |
-
|
249 |
-
while retry_count < max_retries:
|
250 |
-
try:
|
251 |
-
images = [image1, image2, image3]
|
252 |
-
valid_images = [img for img in images if img is not None]
|
253 |
-
|
254 |
-
if not valid_images:
|
255 |
-
if prompt and prompt.strip():
|
256 |
-
logger.info("ํ
์คํธ ํ๋กฌํํธ๋ง์ผ๋ก ์ด๋ฏธ์ง ์์ฑ ์๋")
|
257 |
-
try:
|
258 |
-
result_img, status = generate_with_images(prompt, [], variation_index)
|
259 |
-
if result_img is not None:
|
260 |
-
return result_img, status, prompt
|
261 |
-
except:
|
262 |
-
pass
|
263 |
-
return None, "์ด๋ฏธ์ง๋ฅผ ์
๋ก๋ํ๊ฑฐ๋ ํ
์คํธ ํ๋กฌํํธ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์.", ""
|
264 |
-
|
265 |
-
if prompt and prompt.strip():
|
266 |
-
processed_prompt = preprocess_prompt(prompt, image1, image2, image3)
|
267 |
-
if re.search("[๊ฐ-ํฃ]", processed_prompt):
|
268 |
-
final_prompt = translate_prompt_to_english(processed_prompt)
|
269 |
-
else:
|
270 |
-
final_prompt = processed_prompt
|
271 |
-
else:
|
272 |
-
if len(valid_images) == 1:
|
273 |
-
final_prompt = "Please creatively transform this image into a more vivid and artistic version. Do not include any text or watermarks in the generated image."
|
274 |
-
logger.info("Default prompt generated for single image")
|
275 |
-
elif len(valid_images) == 2:
|
276 |
-
final_prompt = "Please seamlessly composite these two images, integrating their key elements harmoniously into a single image. Do not include any text or watermarks in the generated image."
|
277 |
-
logger.info("Default prompt generated for two images")
|
278 |
-
else:
|
279 |
-
final_prompt = "Please creatively composite these three images, combining their main elements into a cohesive and natural scene. Do not include any text or watermarks in the generated image."
|
280 |
-
logger.info("Default prompt generated for three images")
|
281 |
-
|
282 |
-
result_img, status = generate_with_images(final_prompt, valid_images, variation_index)
|
283 |
-
if result_img is not None:
|
284 |
-
return result_img, status, final_prompt
|
285 |
-
else:
|
286 |
-
last_error = status
|
287 |
-
retry_count += 1
|
288 |
-
logger.warning(f"์ด๋ฏธ์ง ์์ฑ ์คํจ, ์ฌ์๋ {retry_count}/{max_retries}")
|
289 |
-
time.sleep(1)
|
290 |
-
except Exception as e:
|
291 |
-
last_error = "์ฒ๋ฆฌ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค."
|
292 |
-
retry_count += 1
|
293 |
-
logger.exception(f"์ด๋ฏธ์ง ์ฒ๋ฆฌ ์ค ์ค๋ฅ ๋ฐ์, ์ฌ์๋ {retry_count}/{max_retries}")
|
294 |
-
time.sleep(1)
|
295 |
-
|
296 |
-
return None, f"์ต๋ ์ฌ์๋ ํ์({max_retries}ํ) ์ด๊ณผ ํ ์คํจ: {last_error}", prompt
|
297 |
|
298 |
-
def
|
299 |
-
"""
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
while len(results) < 2:
|
327 |
-
results.append(None)
|
328 |
-
|
329 |
-
combined_status = "\n".join(statuses)
|
330 |
-
combined_prompts = "\n".join(prompts)
|
331 |
-
|
332 |
-
return results[0], results[1], combined_status, combined_prompts
|
333 |
|
334 |
# ๋คํฌ๋ชจ๋ ์๋ ์ ์ฉ ์ปค์คํ
CSS ์คํ์ผ
|
335 |
custom_css = """
|
@@ -765,7 +625,6 @@ with gr.Blocks(css=custom_css, theme=gr.themes.Default(
|
|
765 |
)) as demo:
|
766 |
gr.HTML(fontawesome_link)
|
767 |
|
768 |
-
# ํญ ์ ๊ฑฐํ๊ณ ์ด๋ฏธ์ง ์์ฑ๊ธฐ ๋ด์ฉ์ ์ง์ ๋ฐฐ์น
|
769 |
with gr.Row(equal_height=True):
|
770 |
with gr.Column(scale=1):
|
771 |
# ======== ์ด๋ฏธ์ง ์
๋ก๋ ๋ฐ ์ค์ ์น์
========
|
@@ -854,85 +713,23 @@ with gr.Blocks(css=custom_css, theme=gr.themes.Default(
|
|
854 |
)
|
855 |
|
856 |
# ========== ์ด๋ฏธ์ง ์์ฑ๊ธฐ ์ด๋ฒคํธ ์ฐ๊ฒฐ ==========
|
857 |
-
# ๋ฒํผ ์ด๋ฒคํธ ์ฐ๊ฒฐ
|
858 |
-
image_change_btn1.click(
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
)
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
)
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
)
|
873 |
-
|
874 |
-
text_remove_btn.click(
|
875 |
-
fn=lambda: "(#1 ์ด๋ฏธ์ง)์ ์๋ ์ค๊ตญ์ด๋ฅผ ๋ชจ๋ ์ ๊ฑฐํ๋ผ.",
|
876 |
-
inputs=[],
|
877 |
-
outputs=prompt_input
|
878 |
-
)
|
879 |
-
text_change_btn.click(
|
880 |
-
fn=lambda: '(#1์ ํ
์คํธ)๋ฅผ ์คํ์ผ์ ์ ์งํ์ฒด ํ
์คํธ๋ง "Hello"๋ก ๋ฐ๊ฟ๋ผ',
|
881 |
-
inputs=[],
|
882 |
-
outputs=prompt_input
|
883 |
-
)
|
884 |
-
clothes_change_btn1.click(
|
885 |
-
fn=lambda: "(#1์ ์ฌ์ฑ๋ชจ๋ธ)์ด ์ ์ฒด ๋น์จ๊ณผ ํฌ์ฆ๋ ์ ์งํ ์ฒด (#2์ ์ ๊ธ๋ผ์ค)์ (#3์ ์ฒญ๋ฐ์ง)๋ฅผ ์ง์ ๋ชจ๋ธ์ด ์ฐฉ์ฉํ๊ฒ ์ฒ๋ผ ์์ฐ์ค๋ฝ๊ฒ ๋ชจ์ต์ ์์ฑํ๋ผ.",
|
886 |
-
inputs=[],
|
887 |
-
outputs=prompt_input
|
888 |
-
)
|
889 |
-
clothes_change_btn2.click(
|
890 |
-
fn=lambda: "(#1์ ์ฌ์ฑ๋ชจ๋ธ)์ด (#2์ ์ ๊ธ๋ผ์ค)์ ์ฐฉ์ฉํ๊ณ (#3์ ๋ท๋ฐฐ๊ฒฝ์ ์นดํ์ ์ฒด๊ฐ ๋ณด์ด๋ฉฐ) ์์์ ์์ ์๋ ๋ชจ์ต์ ์์ฑํ๋ผ.",
|
891 |
-
inputs=[],
|
892 |
-
outputs=prompt_input
|
893 |
-
)
|
894 |
-
holding_product_btn.click(
|
895 |
-
fn=lambda: "(#1์ ์ฌ์ฑ๋ชจ๋ธ)์ด(#2์ ์์ธ์)์ ๋ค๊ณ ์๋ ์์ฐ์ค๋ฌ์ด ๋ชจ์ต์ ์์ฑํ๋ผ.",
|
896 |
-
inputs=[],
|
897 |
-
outputs=prompt_input
|
898 |
-
)
|
899 |
-
background_change_btn.click(
|
900 |
-
fn=lambda: "(#1์ ์ฌ์ฑ๋ชจ๋ธ)์ด (#2 ์นดํ)์์ ์์ฐ์ค๋ฝ๊ฒ ์๋ ๋ชจ์ต์ ์์ฑํ๋ผ.",
|
901 |
-
inputs=[],
|
902 |
-
outputs=prompt_input
|
903 |
-
)
|
904 |
-
composite_product_btn.click(
|
905 |
-
fn=lambda: "(#1์ ๋ ๊ณ ๋ชจํ)์์ ์ฒญ์์์ด๋ ๊ณ ๋ฅผ ์ ๊ฑฐํ ํ, ๊ทธ ์๋ฆฌ๋ฅผ ์ฃผ๋ณ ๋ฐฐ๊ฒฝ๊ณผ ์์ฐ์ค๋ฝ๊ฒ ์ด์ฐ๋ฌ์ง๋๋ก ์ฑ์์ฃผ์ธ์. ๋จ, ์ด๋ฏธ์ง์ ๋ค๋ฅธ ๋ถ๋ถ์ ์ฃผ์ ์์๋ ๋์ผํ๊ฒ ์ ์ง ํด์ผํ๋ค.",
|
906 |
-
inputs=[],
|
907 |
-
outputs=prompt_input
|
908 |
-
)
|
909 |
-
outpainting_btn.click(
|
910 |
-
fn=lambda: "(#1 ์ด๋ฏธ์ง)๋ฅผ ์๋ณธ๊ทธ๋๋ก ์ค์์ ๋๊ณ ๋น์จ๋ก ์ ์งํ ์ฒด ์์๋ ๋ฐ ์ข์ฐ๋ก ํฌ๊ฒ ํ์ฅํ๋ผ.",
|
911 |
-
inputs=[],
|
912 |
-
outputs=prompt_input
|
913 |
-
|
914 |
-
)
|
915 |
-
food_btn_1.click(
|
916 |
-
fn=lambda: "(#1์
๋ฌ๋)์ ๋ด์ ์ฉ๊ธฐ๋ ๋ฒ๋ฆฌ๊ณ ๋๊ณ ํฐ ์์ ์ ์์ (#1์
๋ฌ๋)์์๋ง ๊ฐ๋ ์ฑ์์ ์์
์ ์ธ ๊ฐ๋๋ก ์ด์ธ๋ฆฌ๋ ์ํ๊ณผ ํจ๊ป ํ๋ ์ดํ
ํ ๋ชจ์ต์ ์ด๋ฏธ์ง๋ก ์์ฑํ๋ผ. ",
|
917 |
-
inputs=[],
|
918 |
-
outputs=prompt_input
|
919 |
-
)
|
920 |
-
food_btn_2.click(
|
921 |
-
fn=lambda: "(#2 ํ๋ ์ดํ
ํ ์ด๋ฏธ์ง)์ ๋ด๊ธด ์์์ (#1 ์๋ฌ๋)๋ก ๋ฐ๊พธ๊ณ ๋๋จธ์ง๋ ์๋๋ฅผ ์ ์งํ ์ฒด ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๋ผ.",
|
922 |
-
inputs=[],
|
923 |
-
outputs=prompt_input
|
924 |
-
)
|
925 |
-
|
926 |
-
food_btn_3.click(
|
927 |
-
fn=lambda: "(#1์ปต)์ ๋ธ๊ธฐ, ๋ฐ๋๋ผ, ์ด์ฝ ์์ด์คํฌ๋ฆผ์ ๋ด๊ณ ๊ทธ ์์ ์ด์ฝ ์๋ฝ์ด ํ๋ฅด๊ฒ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๋ผ.",
|
928 |
-
inputs=[],
|
929 |
-
outputs=prompt_input
|
930 |
-
)
|
931 |
|
932 |
# ๋จ์ผ ์ด๋ฏธ์ง ์์ฑ ๋ฒํผ ์ด๋ฒคํธ ์ฐ๊ฒฐ
|
933 |
-
def generate_single_image(image1, image2, image3, prompt):
|
934 |
-
return process_images_with_prompt(image1, image2, image3, prompt, 0, 3)
|
935 |
-
|
936 |
submit_single_btn.click(
|
937 |
fn=generate_single_image,
|
938 |
inputs=[image1_input, image2_input, image3_input, prompt_input],
|
@@ -947,13 +744,5 @@ with gr.Blocks(css=custom_css, theme=gr.themes.Default(
|
|
947 |
)
|
948 |
|
949 |
# ์ ํ๋ฆฌ์ผ์ด์
์คํ
|
950 |
-
|
951 |
-
|
952 |
-
endpoint = get_api_endpoint()
|
953 |
-
if endpoint:
|
954 |
-
logger.info("์ปจํธ๋กค ํ์๊ฐ ์์๋์์ต๋๋ค.")
|
955 |
-
else:
|
956 |
-
logger.warning("API ์ค์ ์ ํ์ธํด์ฃผ์ธ์.")
|
957 |
-
|
958 |
-
demo.queue()
|
959 |
-
demo.launch(share=False, inbrowser=True, width="100%")
|
|
|
10 |
from io import BytesIO
|
11 |
from datetime import datetime, timedelta
|
12 |
import random
|
|
|
|
|
13 |
from dotenv import load_dotenv
|
14 |
+
from gradio_client import Client, handle_file
|
15 |
|
16 |
load_dotenv()
|
17 |
|
|
|
19 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
20 |
logger = logging.getLogger(__name__)
|
21 |
|
22 |
+
# ํด๋ผ์ด์ธํธ ์ ๋ณด ๋ก๊ทธ์์ ์จ๊ธฐ๊ธฐ
|
23 |
+
logging.getLogger('gradio_client').setLevel(logging.WARNING)
|
24 |
+
|
25 |
+
# API ์๋ํฌ์ธํธ ์ค์ (ํ๊ฒฝ๋ณ์์์๋ง ์ค์ )
|
26 |
+
API_ENDPOINT = os.environ.get("API_ENDPOINT", "")
|
27 |
+
|
28 |
+
if not API_ENDPOINT:
|
29 |
+
raise ValueError("API_ENDPOINT ํ๊ฒฝ๋ณ์๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค.")
|
30 |
+
|
31 |
+
# ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
|
32 |
+
try:
|
33 |
+
client = Client(API_ENDPOINT)
|
34 |
+
logger.info("ํด๋ผ์ด์ธํธ ์ด๊ธฐํ ์๋ฃ")
|
35 |
+
except Exception as e:
|
36 |
+
logger.error(f"ํด๋ผ์ด์ธํธ ์ด๊ธฐํ ์คํจ: {e}")
|
37 |
+
raise
|
38 |
+
|
39 |
+
def safe_client_call(api_name, **kwargs):
|
40 |
+
"""์์ ํ ํด๋ผ์ด์ธํธ ํธ์ถ ํจ์"""
|
41 |
+
try:
|
42 |
+
return client.predict(api_name=api_name, **kwargs)
|
43 |
+
except Exception as e:
|
44 |
+
logger.error(f"API ํธ์ถ ์คํจ ({api_name}): {e}")
|
45 |
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
|
47 |
+
def convert_image_to_file(image):
|
48 |
+
"""PIL Image ๊ฐ์ฒด๋ฅผ ์์ ํ์ผ๋ก ๋ณํ"""
|
49 |
if image is None:
|
50 |
return None
|
51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
try:
|
53 |
+
# PIL Image ๊ฐ์ฒด์ธ ๊ฒฝ์ฐ
|
54 |
+
if hasattr(image, 'save'):
|
55 |
+
# ์์ ํ์ผ ์์ฑ
|
56 |
+
temp_file = tempfile.NamedTemporaryFile(suffix='.png', delete=False)
|
57 |
+
image.save(temp_file.name, format='PNG')
|
58 |
+
temp_file.close()
|
59 |
+
return temp_file.name
|
60 |
+
# ์ด๋ฏธ ํ์ผ ๊ฒฝ๋ก์ธ ๊ฒฝ์ฐ
|
61 |
+
elif isinstance(image, str):
|
62 |
+
return image
|
63 |
+
# ๊ธฐํ ๊ฒฝ์ฐ
|
64 |
+
else:
|
65 |
+
return image
|
66 |
+
except Exception as e:
|
67 |
+
logger.error(f"์ด๋ฏธ์ง ํ์ผ ๋ณํ ์คํจ: {e}")
|
68 |
+
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
+
# ========== ์ด๋ฏธ์ง ์์ฑ๊ธฐ ๊ด๋ จ ํจ์ (ํด๋ผ์ด์ธํธ API ํ์ฉ) ==========
|
71 |
+
def generate_single_image(image1, image2, image3, prompt):
|
72 |
+
"""๋จ์ผ ์ด๋ฏธ์ง ์์ฑ - ์๋ณธ ํจ์๋ช
์ ์ง"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
try:
|
74 |
+
# ์ด๋ฏธ์ง ํ์ผ ์ฒ๋ฆฌ - PIL Image๋ฅผ ์์ ํ์ผ๋ก ๋ณํ
|
75 |
+
image1_path = convert_image_to_file(image1)
|
76 |
+
image2_path = convert_image_to_file(image2)
|
77 |
+
image3_path = convert_image_to_file(image3)
|
78 |
+
|
79 |
+
# handle_file๋ก ์ฒ๋ฆฌ
|
80 |
+
image1_file = handle_file(image1_path) if image1_path else None
|
81 |
+
image2_file = handle_file(image2_path) if image2_path else None
|
82 |
+
image3_file = handle_file(image3_path) if image3_path else None
|
83 |
+
|
84 |
+
result = safe_client_call(
|
85 |
+
"/generate_single_image",
|
86 |
+
image1=image1_file,
|
87 |
+
image2=image2_file,
|
88 |
+
image3=image3_file,
|
89 |
+
prompt=prompt
|
90 |
+
)
|
91 |
+
|
92 |
+
if result:
|
93 |
+
return result[0], result[1], result[2]
|
|
|
94 |
else:
|
95 |
+
return None, "API ํธ์ถ ์คํจ", ""
|
96 |
+
|
97 |
+
except Exception as e:
|
98 |
+
logger.error(f"๋จ์ผ ์ด๋ฏธ์ง ์์ฑ ์คํจ: {e}")
|
99 |
+
return None, f"์ค๋ฅ ๋ฐ์: {str(e)}", ""
|
100 |
+
|
101 |
+
def generate_multiple_images(image1, image2, image3, prompt, progress=gr.Progress()):
|
102 |
+
"""๋ค์ค ์ด๋ฏธ์ง ์์ฑ - ์๋ณธ ํจ์๋ช
์ ์ง"""
|
|
|
103 |
try:
|
104 |
+
progress(0, desc="์ด๋ฏธ์ง ์์ฑ ์ค๋น ์ค...")
|
105 |
+
|
106 |
+
# ์ด๋ฏธ์ง ํ์ผ ์ฒ๋ฆฌ - PIL Image๋ฅผ ์์ ํ์ผ๋ก ๋ณํ
|
107 |
+
image1_path = convert_image_to_file(image1)
|
108 |
+
image2_path = convert_image_to_file(image2)
|
109 |
+
image3_path = convert_image_to_file(image3)
|
110 |
+
|
111 |
+
# handle_file๋ก ์ฒ๋ฆฌ
|
112 |
+
image1_file = handle_file(image1_path) if image1_path else None
|
113 |
+
image2_file = handle_file(image2_path) if image2_path else None
|
114 |
+
image3_file = handle_file(image3_path) if image3_path else None
|
115 |
+
|
116 |
+
progress(0.5, desc="์ด๋ฏธ์ง ์์ฑ ์ค...")
|
117 |
+
|
118 |
+
result = safe_client_call(
|
119 |
+
"/generate_multiple_images",
|
120 |
+
image1=image1_file,
|
121 |
+
image2=image2_file,
|
122 |
+
image3=image3_file,
|
123 |
+
prompt=prompt
|
124 |
+
)
|
125 |
+
|
126 |
+
progress(1.0, desc="์ด๋ฏธ์ง ์์ฑ ์๋ฃ!")
|
127 |
|
128 |
+
if result:
|
129 |
+
return result[0], result[1], result[2], result[3]
|
|
|
|
|
130 |
else:
|
131 |
+
return None, None, "API ํธ์ถ ์คํจ", ""
|
132 |
+
|
133 |
except Exception as e:
|
134 |
+
logger.error(f"๋ค์ค ์ด๋ฏธ์ง ์์ฑ ์คํจ: {e}")
|
135 |
+
return None, None, f"์ค๋ฅ ๋ฐ์: {str(e)}", ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
|
137 |
+
# ========== ํ๋กฌํํธ ํ
ํ๋ฆฟ ํจ์๋ค - ํด๋ผ์ด์ธํธ API ํ์ฉ ==========
|
138 |
+
def get_prompt_template_1():
|
139 |
+
"""ํ๋กฌํํธ ํ
ํ๋ฆฟ 1 - ๋ถ๋ถ๋ณ๊ฒฝ-1"""
|
140 |
+
return "(#1์ ์ฌ์ฑ)์ด ์ด์ง ๋ค๋ก ๋์๋ณด๋ ๋ชจ์ต์ผ๋ก ์ต๋ํ ์ด์ seed๋ฅผ ์ ์งํํ
์์ฐ์ค๋ฝ๊ฒ ๋ณ๊ฒฝํ๋ผ."
|
|
|
|
|
|
|
141 |
|
142 |
+
def get_prompt_template_2():
|
143 |
+
"""ํ๋กฌํํธ ํ
ํ๋ฆฟ 2 - ๋ถ๋ถ๋ณ๊ฒฝ-2"""
|
144 |
+
return "(#1 ๋ ๋ชจ๋ชจํ)์์ ์ฒญ์์์ด๋ ๊ณ ๋ง ๊ฒ์์ ๊ณ ๋๋ ๊ณ ๋ก ๋ณ๊ฒฝํ๊ณ ๋๋จธ์ง ๋ถ๋ถ์ seed๋ฅผ ๋ณ๊ฒฝ์ ํ์ง๋ง๋ผ."
|
145 |
|
146 |
+
def get_prompt_template_3():
|
147 |
+
"""ํ๋กฌํํธ ํ
ํ๋ฆฟ 3 - ๋ถ๋ถ๋ณ๊ฒฝ-3"""
|
148 |
+
return "(#1 ์ฌํ์ฉ ์ผ์๋ฐ์ค)์์ ์ผ์์ด ๋ด๊ธด 3์์ ์ฝ๋ผ๊ฐ ๋์ฌ์๋ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๋ผ."
|
149 |
|
150 |
+
def get_prompt_template_4():
|
151 |
+
"""ํ๋กฌํํธ ํ
ํ๋ฆฟ 4 - ๊ธ์์ง์ฐ๊ธฐ"""
|
152 |
+
return "(#1 ์ด๋ฏธ์ง)์ ์๋ ์ค๊ตญ์ด๋ฅผ ๋ชจ๋ ์ ๊ฑฐํ๋ผ."
|
153 |
|
154 |
+
def get_prompt_template_5():
|
155 |
+
"""ํ๋กฌํํธ ํ
ํ๋ฆฟ 5 - ๊ธ์๋ณ๊ฒฝ"""
|
156 |
+
return '(#1์ ํ
์คํธ)๋ฅผ ์คํ์ผ์ ์ ์งํ์ฒด ํ
์คํธ๋ง "Hello"๋ก ๋ฐ๊ฟ๋ผ'
|
157 |
|
158 |
+
def get_prompt_template_6():
|
159 |
+
"""ํ๋กฌํํธ ํ
ํ๋ฆฟ 6 - ์ํ์ฐฉ์ฉ-1"""
|
160 |
+
return "(#1์ ์ฌ์ฑ๋ชจ๋ธ)์ด ์ ์ฒด ๋น์จ๊ณผ ํฌ์ฆ๋ ์ ์งํ ์ฒด (#2์ ์ ๊ธ๋ผ์ค)์ (#3์ ์ฒญ๋ฐ์ง)๋ฅผ ์ง์ ๋ชจ๋ธ์ด ์ฐฉ์ฉํ๊ฒ ์ฒ๋ผ ์์ฐ์ค๋ฝ๊ฒ ๋ชจ์ต์ ์์ฑํ๋ผ."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
|
162 |
+
def get_prompt_template_7():
|
163 |
+
"""ํ๋กฌํํธ ํ
ํ๋ฆฟ 7 - ์ํ์ฐฉ์ฉ-2"""
|
164 |
+
return "(#1์ ์ฌ์ฑ๋ชจ๋ธ)์ด (#2์ ์ ๊ธ๋ผ์ค)์ ์ฐฉ์ฉํ๊ณ (#3์ ๋ท๋ฐฐ๊ฒฝ์ ์นดํ์ ์ฒด๊ฐ ๋ณด์ด๋ฉฐ) ์์์ ์์ ์๋ ๋ชจ์ต์ ์์ฑํ๋ผ."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
|
166 |
+
def get_prompt_template_8():
|
167 |
+
"""ํ๋กฌํํธ ํ
ํ๋ฆฟ 8 - ์ํ๋ค๊ณ """
|
168 |
+
return "(#1์ ์ฌ์ฑ๋ชจ๋ธ)์ด(#2์ ์์ธ์)์ ๋ค๊ณ ์๋ ์์ฐ์ค๋ฌ์ด ๋ชจ์ต์ ์์ฑํ๋ผ."
|
169 |
+
|
170 |
+
def get_prompt_template_9():
|
171 |
+
"""ํ๋กฌํํธ ํ
ํ๋ฆฟ 9 - ๋ฐฐ๊ฒฝ๋ฐ๊พธ๊ธฐ"""
|
172 |
+
return "(#1์ ์ฌ์ฑ๋ชจ๋ธ)์ด (#2 ์นดํ)์์ ์์ฐ์ค๋ฝ๊ฒ ์๋ ๋ชจ์ต์ ์์ฑํ๋ผ."
|
173 |
+
|
174 |
+
def get_prompt_template_10():
|
175 |
+
"""ํ๋กฌํํธ ํ
ํ๋ฆฟ 10 - ๋ถ๋ถ์ง์ฐ๊ธฐ"""
|
176 |
+
return "(#1์ ๋ ๊ณ ๋ชจํ)์์ ์ฒญ์์์ด๋ ๊ณ ๋ฅผ ์ ๊ฑฐํ ํ, ๊ทธ ์๋ฆฌ๋ฅผ ์ฃผ๋ณ ๋ฐฐ๊ฒฝ๊ณผ ์์ฐ์ค๋ฝ๊ฒ ์ด์ฐ๏ฟฝ๏ฟฝ๏ฟฝ์ง๋๋ก ์ฑ์์ฃผ์ธ์. ๋จ, ์ด๋ฏธ์ง์ ๋ค๋ฅธ ๋ถ๋ถ์ ์ฃผ์ ์์๋ ๋์ผํ๊ฒ ์ ์ง ํด์ผํ๋ค."
|
177 |
+
|
178 |
+
def get_prompt_template_11():
|
179 |
+
"""ํ๋กฌํํธ ํ
ํ๋ฆฟ 11 - ์ด๋ฏธ์งํ์ฅ"""
|
180 |
+
return "(#1 ์ด๋ฏธ์ง)๋ฅผ ์๋ณธ๊ทธ๋๋ก ์ค์์ ๋๊ณ ๋น์จ๋ก ์ ์งํ ์ฒด ์์๋ ๋ฐ ์ข์ฐ๋ก ํฌ๊ฒ ํ์ฅํ๋ผ."
|
181 |
+
|
182 |
+
def get_prompt_template_12():
|
183 |
+
"""ํ๋กฌํํธ ํ
ํ๋ฆฟ 12 - ํ๋ ์ดํ
-1"""
|
184 |
+
return "(#1์
๋ฌ๋)์ ๋ด์ ์ฉ๊ธฐ๋ ๋ฒ๋ฆฌ๊ณ ๋๊ณ ํฐ ์์ ์ ์์ (#1์
๋ฌ๋)์์๋ง ๊ฐ๋ ์ฑ์์ ์์
์ ์ธ ๊ฐ๋๋ก ์ด์ธ๋ฆฌ๋ ์ํ๊ณผ ํจ๊ป ํ๋ ์ดํ
ํ ๋ชจ์ต์ ์ด๋ฏธ์ง๋ก ์์ฑํ๋ผ. "
|
185 |
+
|
186 |
+
def get_prompt_template_13():
|
187 |
+
"""ํ๋กฌํํธ ํ
ํ๋ฆฟ 13 - ํ๋ ์ดํ
-2"""
|
188 |
+
return "(#2 ํ๋ ์ดํ
ํ ์ด๋ฏธ์ง)์ ๋ด๊ธด ์์์ (#1 ์๋ฌ๋)๋ก ๋ฐ๊พธ๊ณ ๋๋จธ์ง๋ ์๋๋ฅผ ์ ์งํ ์ฒด ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๋ผ."
|
189 |
+
|
190 |
+
def get_prompt_template_14():
|
191 |
+
"""ํ๋กฌํํธ ํ
ํ๋ฆฟ 14 - ํ๋ ์ดํ
-3"""
|
192 |
+
return "(#1์ปต)์ ๋ธ๊ธฐ, ๋ฐ๋๋ผ, ์ด์ฝ ์์ด์คํฌ๋ฆผ์ ๋ด๊ณ ๊ทธ ์์ ์ด์ฝ ์๋ฝ์ด ํ๋ฅด๊ฒ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๋ผ."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
|
194 |
# ๋คํฌ๋ชจ๋ ์๋ ์ ์ฉ ์ปค์คํ
CSS ์คํ์ผ
|
195 |
custom_css = """
|
|
|
625 |
)) as demo:
|
626 |
gr.HTML(fontawesome_link)
|
627 |
|
|
|
628 |
with gr.Row(equal_height=True):
|
629 |
with gr.Column(scale=1):
|
630 |
# ======== ์ด๋ฏธ์ง ์
๋ก๋ ๋ฐ ์ค์ ์น์
========
|
|
|
713 |
)
|
714 |
|
715 |
# ========== ์ด๋ฏธ์ง ์์ฑ๊ธฐ ์ด๋ฒคํธ ์ฐ๊ฒฐ ==========
|
716 |
+
# ๋ฒํผ ์ด๋ฒคํธ ์ฐ๊ฒฐ - ํ๋กฌํํธ ํ
ํ๋ฆฟ
|
717 |
+
image_change_btn1.click(fn=get_prompt_template_1, outputs=prompt_input)
|
718 |
+
image_change_btn2.click(fn=get_prompt_template_2, outputs=prompt_input)
|
719 |
+
image_change_btn3.click(fn=get_prompt_template_3, outputs=prompt_input)
|
720 |
+
text_remove_btn.click(fn=get_prompt_template_4, outputs=prompt_input)
|
721 |
+
text_change_btn.click(fn=get_prompt_template_5, outputs=prompt_input)
|
722 |
+
clothes_change_btn1.click(fn=get_prompt_template_6, outputs=prompt_input)
|
723 |
+
clothes_change_btn2.click(fn=get_prompt_template_7, outputs=prompt_input)
|
724 |
+
holding_product_btn.click(fn=get_prompt_template_8, outputs=prompt_input)
|
725 |
+
background_change_btn.click(fn=get_prompt_template_9, outputs=prompt_input)
|
726 |
+
composite_product_btn.click(fn=get_prompt_template_10, outputs=prompt_input)
|
727 |
+
outpainting_btn.click(fn=get_prompt_template_11, outputs=prompt_input)
|
728 |
+
food_btn_1.click(fn=get_prompt_template_12, outputs=prompt_input)
|
729 |
+
food_btn_2.click(fn=get_prompt_template_13, outputs=prompt_input)
|
730 |
+
food_btn_3.click(fn=get_prompt_template_14, outputs=prompt_input)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
731 |
|
732 |
# ๋จ์ผ ์ด๋ฏธ์ง ์์ฑ ๋ฒํผ ์ด๋ฒคํธ ์ฐ๊ฒฐ
|
|
|
|
|
|
|
733 |
submit_single_btn.click(
|
734 |
fn=generate_single_image,
|
735 |
inputs=[image1_input, image2_input, image3_input, prompt_input],
|
|
|
744 |
)
|
745 |
|
746 |
# ์ ํ๋ฆฌ์ผ์ด์
์คํ
|
747 |
+
demo.queue()
|
748 |
+
demo.launch(share=False, inbrowser=True, width="100%")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|