Update app.py
Browse files
app.py
CHANGED
@@ -33,7 +33,6 @@ COLORFUL_PATTERN_BACKGROUNDS = {}
|
|
33 |
ABSTRACT_BACKGROUNDS = {}
|
34 |
JEWELRY_BACKGROUNDS = {} # ์ฅฌ์ผ๋ฆฌ ๋ฐฐ๊ฒฝ ์ ์ญ ๋ณ์ ์ถ๊ฐ
|
35 |
|
36 |
-
|
37 |
# ------------------- ๋ฐฐ๊ฒฝ JSON ํ์ผ ๋ก๋ ํจ์ -------------------
|
38 |
def load_background_json(filename):
|
39 |
"""๋ฐฐ๊ฒฝ JSON ํ์ผ ๋ก๋ ํจ์"""
|
@@ -56,22 +55,18 @@ def initialize_backgrounds():
|
|
56 |
global SIMPLE_BACKGROUNDS, STUDIO_BACKGROUNDS, NATURE_BACKGROUNDS, INDOOR_BACKGROUNDS
|
57 |
global TECHNOLOGY_BACKGROUNDS, COLORFUL_PATTERN_BACKGROUNDS, ABSTRACT_BACKGROUNDS
|
58 |
global JEWELRY_BACKGROUNDS # ์ฅฌ์ผ๋ฆฌ ๋ฐฐ๊ฒฝ ์ถ๊ฐ
|
59 |
-
|
60 |
|
61 |
-
# ๋๋ ํ ๋ฆฌ ๋ด ๋ชจ๋ ํ์ผ ๋ก๊น
|
62 |
logger.info(f"Backgrounds ๋๋ ํ ๋ฆฌ ๊ฒฝ๋ก: {BACKGROUNDS_DIR}")
|
63 |
logger.info(f"๋๋ ํ ๋ฆฌ ๋ด ํ์ผ ๋ชฉ๋ก: {os.listdir(BACKGROUNDS_DIR)}")
|
64 |
|
65 |
-
# ๊ฐ ๋ฐฐ๊ฒฝ ํ์ผ ๋ก๋
|
66 |
SIMPLE_BACKGROUNDS = load_background_json("simple_backgrounds.json")
|
67 |
STUDIO_BACKGROUNDS = load_background_json("studio_backgrounds.json")
|
68 |
NATURE_BACKGROUNDS = load_background_json("nature_backgrounds.json")
|
69 |
INDOOR_BACKGROUNDS = load_background_json("indoor_backgrounds.json")
|
70 |
-
TECHNOLOGY_BACKGROUNDS = load_background_json("tech-backgrounds-final.json")
|
71 |
-
COLORFUL_PATTERN_BACKGROUNDS = load_background_json("colorful-pattern-backgrounds.json")
|
72 |
ABSTRACT_BACKGROUNDS = load_background_json("abstract_backgrounds.json")
|
73 |
JEWELRY_BACKGROUNDS = load_background_json("jewelry_backgrounds.json")
|
74 |
-
|
75 |
|
76 |
# ๊ธฐ๋ณธ๊ฐ ์ค์ (ํ์ผ์ด ์๊ฑฐ๋ ๋น์ด์๋ ๊ฒฝ์ฐ)
|
77 |
if not SIMPLE_BACKGROUNDS:
|
@@ -93,10 +88,9 @@ def initialize_backgrounds():
|
|
93 |
|
94 |
logger.info("๋ชจ๋ ๋ฐฐ๊ฒฝ ์ต์
์ด๊ธฐํ ์๋ฃ")
|
95 |
|
96 |
-
# ๋ฐฐ๊ฒฝ ๋๋กญ๋ค์ด ์ด๊ธฐํ๋ฅผ ์ํ ํจ์
|
97 |
def initialize_dropdowns():
|
98 |
"""๋๋กญ๋ค์ด ๋ฉ๋ด ์ด๊ธฐํ ํจ์"""
|
99 |
-
# ๊ฐ ๋ฐฐ๊ฒฝ ์ ํ๋ณ ๋๋กญ๋ค์ด ์ ํ ๋ชฉ๋ก ์์ฑ
|
100 |
simple_choices = list(SIMPLE_BACKGROUNDS.keys())
|
101 |
studio_choices = list(STUDIO_BACKGROUNDS.keys())
|
102 |
nature_choices = list(NATURE_BACKGROUNDS.keys())
|
@@ -105,8 +99,6 @@ def initialize_dropdowns():
|
|
105 |
colorful_choices = list(COLORFUL_PATTERN_BACKGROUNDS.keys())
|
106 |
abstract_choices = list(ABSTRACT_BACKGROUNDS.keys())
|
107 |
jewelry_choices = list(JEWELRY_BACKGROUNDS.keys())
|
108 |
-
|
109 |
-
|
110 |
|
111 |
return {
|
112 |
"simple": simple_choices,
|
@@ -116,10 +108,9 @@ def initialize_dropdowns():
|
|
116 |
"tech": tech_choices,
|
117 |
"colorful": colorful_choices,
|
118 |
"abstract": abstract_choices,
|
119 |
-
"jewelry": jewelry_choices,
|
120 |
}
|
121 |
|
122 |
-
|
123 |
# ------------------- ๊ธฐ๋ณธ ์ ํธ๋ฆฌํฐ ํจ์ -------------------
|
124 |
def save_binary_file(file_name, data):
|
125 |
with open(file_name, "wb") as f:
|
@@ -191,7 +182,6 @@ def generate_with_images(prompt, images, variation_index=0):
|
|
191 |
client = genai.Client(api_key=api_key)
|
192 |
logger.info(f"Gemini API ์์ฒญ ์์ - ํ๋กฌํํธ: {prompt}, ๋ณํ ์ธ๋ฑ์ค: {variation_index}")
|
193 |
|
194 |
-
# ํฅ์๋ ๋ณํ ์ ๋ฏธ์ฌ
|
195 |
variation_suffixes = [
|
196 |
" Create this as a professional studio product shot with precise focus on the product details. Do not add any text, watermarks, or labels to the image.",
|
197 |
" Create this as a high-contrast artistic studio shot with dramatic lighting and shadows. Do not add any text, watermarks, or labels to the image.",
|
@@ -210,16 +200,15 @@ def generate_with_images(prompt, images, variation_index=0):
|
|
210 |
contents.append(img)
|
211 |
logger.info(f"์ด๋ฏธ์ง #{idx} ์ถ๊ฐ๋จ")
|
212 |
|
213 |
-
# ํฅ์๋ ์์ฑ ์ค์ - ๋ ๋์ temperature๋ก ์ฐฝ์์ฑ ์ฆ๊ฐ, ๋ ๋์ max_output_tokens
|
214 |
response = client.models.generate_content(
|
215 |
model="gemini-2.0-flash-exp-image-generation",
|
216 |
contents=contents,
|
217 |
config=types.GenerateContentConfig(
|
218 |
response_modalities=['Text', 'Image'],
|
219 |
-
temperature=1.05,
|
220 |
-
top_p=0.97,
|
221 |
-
top_k=50,
|
222 |
-
max_output_tokens=10240
|
223 |
)
|
224 |
)
|
225 |
|
@@ -274,21 +263,16 @@ def process_images_with_prompt(image1, prompt, variation_index=0, max_retries=3)
|
|
274 |
# ------------------- ํ๋กฌํํธ ๊ด๋ จ ํจ์ -------------------
|
275 |
def filter_prompt_only(prompt):
|
276 |
"""Gemini์ ์ค๋ช
๋ฐ ๋ถํ์ํ ๋ฉ์์ง๋ฅผ ์ ๊ฑฐํ๊ณ ์ค์ ํ๋กฌํํธ๋ง ์ถ์ถํ๋ ํจ์"""
|
277 |
-
|
278 |
-
# ์ฝ๋ ๋ธ๋ก ๋ด๋ถ์ ํ๋กฌํํธ ์ฐพ๊ธฐ
|
279 |
code_block_pattern = r"```\s*(.*?)```"
|
280 |
code_match = re.search(code_block_pattern, prompt, re.DOTALL)
|
281 |
if code_match:
|
282 |
return code_match.group(1).strip()
|
283 |
|
284 |
-
# Midjourney ํ๋ผ๋ฏธํฐ๋ฅผ ํฌํจํ๋ ํ๋กฌํํธ ๋ถ๋ถ ์ฐพ๊ธฐ
|
285 |
if "--ar 1:1" in prompt:
|
286 |
lines = prompt.split('\n')
|
287 |
prompt_lines = []
|
288 |
in_prompt = False
|
289 |
-
|
290 |
for line in lines:
|
291 |
-
# ํ๋กฌํํธ ์์ ๋ถ๋ถ ์ธ์ (์ผ๋ฐ์ ์ธ ์ ํ ์ค๋ช
์ด๋ 'Magazine-worthy' ๊ฐ์ ํค์๋๋ก ์์)
|
292 |
if (not in_prompt and
|
293 |
("product" in line.lower() or
|
294 |
"magazine" in line.lower() or
|
@@ -296,18 +280,13 @@ def filter_prompt_only(prompt):
|
|
296 |
"photography" in line.lower())):
|
297 |
in_prompt = True
|
298 |
prompt_lines.append(line)
|
299 |
-
# ์ด๋ฏธ ํ๋กฌํํธ ์์ญ์ ์๋ ๊ฒฝ์ฐ ๊ณ์ ์ถ๊ฐ
|
300 |
elif in_prompt:
|
301 |
-
# ์ค๋ช
์ด๋ ๋ฉํ ํ
์คํธ๊ฐ ์์๋๋ฉด ์ค๋จ
|
302 |
if "explanation" in line.lower() or "let me know" in line.lower():
|
303 |
break
|
304 |
prompt_lines.append(line)
|
305 |
-
|
306 |
-
# ํ๋กฌํํธ ๋ผ์ธ ํฉ์น๊ธฐ
|
307 |
if prompt_lines:
|
308 |
return '\n'.join(prompt_lines).strip()
|
309 |
|
310 |
-
# ์ ๋ฐฉ๋ฒ์ผ๋ก ์ฐพ์ง ๋ชปํ ๊ฒฝ์ฐ ์๋ณธ ๋ฐํ
|
311 |
return prompt.strip()
|
312 |
|
313 |
def get_selected_background_info(bg_type, simple, studio, nature, indoor, tech, colorful, abstract, jewelry):
|
@@ -354,14 +333,12 @@ def get_selected_background_info(bg_type, simple, studio, nature, indoor, tech,
|
|
354 |
"name": abstract,
|
355 |
"english": ABSTRACT_BACKGROUNDS.get(abstract, "abstract background")
|
356 |
}
|
357 |
-
|
358 |
elif bg_type == "์ฅฌ์ผ๋ฆฌ ๋ฐฐ๊ฒฝ":
|
359 |
return {
|
360 |
"category": "์ฅฌ์ผ๋ฆฌ ๋ฐฐ๊ฒฝ",
|
361 |
"name": jewelry,
|
362 |
"english": JEWELRY_BACKGROUNDS.get(jewelry, "jewelry backdrop")
|
363 |
}
|
364 |
-
|
365 |
else:
|
366 |
return {
|
367 |
"category": "๊ธฐ๋ณธ ๋ฐฐ๊ฒฝ",
|
@@ -369,14 +346,11 @@ def get_selected_background_info(bg_type, simple, studio, nature, indoor, tech,
|
|
369 |
"english": "white background"
|
370 |
}
|
371 |
|
372 |
-
# ------------------- ํ๋กฌํํธ ์์ฑ ํจ์ -------------------
|
373 |
def generate_enhanced_system_instruction():
|
374 |
"""ํฅ์๋ ์์คํ
์ธ์คํธ๋ญ์
์์ฑ ํจ์"""
|
375 |
return """๋น์ ์ ์ํ ์ด๋ฏธ์ง์ ๋ฐฐ๊ฒฝ์ ๋ณ๊ฒฝํ๊ธฐ ์ํ ์ต๊ณ ํ์ง์ ํ๋กฌํํธ๋ฅผ ์์ฑํ๋ ์ ๋ฌธ๊ฐ์
๋๋ค.
|
376 |
์ฌ์ฉ์๊ฐ ์ ๊ณตํ๋ ์ํ๋ช
, ๋ฐฐ๊ฒฝ ์ ํ, ์ถ๊ฐ ์์ฒญ์ฌํญ์ ๋ฐํ์ผ๋ก ๋ฏธ๋์ ๋(Midjourney)์ ์ฌ์ฉํ ์ ์๋ ์์ธํ๊ณ ์ ๋ฌธ์ ์ธ ํ๋กฌํํธ๋ฅผ ์์ด๋ก ์์ฑํด์ฃผ์ธ์.
|
377 |
-
|
378 |
๋ค์ ๊ฐ์ด๋๋ผ์ธ์ ๋ฐ๋์ ์ค์ํด์ผ ํฉ๋๋ค:
|
379 |
-
|
380 |
1. ์ํ์ "#1"๋ก ์ง์ ํ์ฌ ์ฐธ์กฐํฉ๋๋ค. (์: "skincare tube (#1)")
|
381 |
2. *** ๋งค์ฐ ์ค์: ์ํ์ ์๋ ํน์ฑ(๋์์ธ, ์์, ํํ, ๋ก๊ณ , ํจํค์ง ๋ฑ)์ ์ด๋ค ์ํฉ์์๋ ์ ๋ ๋ณ๊ฒฝํ์ง ์์ต๋๋ค. ***
|
382 |
3. *** ์ํ์ ๋ณธ์ง์ ํน์ฑ์ ์ ์งํ๋, ์ํ์ ํฌ์ปค์ค๋ฅผ ๋ง์ถฐ ๋ชจ๋ ์ธ๋ถ ์ฌํญ์ด ์ ๋ช
ํ๊ฒ ๋๋ฌ๋๋๋ก ํ๋ฉฐ,
|
@@ -396,8 +370,8 @@ def generate_enhanced_system_instruction():
|
|
396 |
- "ultra high definition"
|
397 |
- "crystal clear details"
|
398 |
10. ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ๊ตฌ์ฒด์ ์ธ ๋ฐฐ๊ฒฝ๊ณผ ์ถ๊ฐ ์์ฒญ์ฌํญ์ ํ๋กฌํํธ์ ์ ํํ ๋ฐ์ํ๊ณ ํ์ฅํฉ๋๋ค.
|
399 |
-
11. ํ๋กฌํํธ ๋์ "--ar 1:1 --s 750 --q 2 --v 5.2" ํ๋ผ๋ฏธํฐ๋ฅผ ์ถ๊ฐํ์ฌ ๋ฏธ๋์ ๋์์ ๊ณ ํ์ง ์ ์ฌ๊ฐํ ๋น์จ์ ๊ฐ์ ํฉ๋๋ค.
|
400 |
-
12. ๋งค์ฐ ์ค์: ํ๋กฌํํธ ์ธ์ ๋ค๋ฅธ ์ค๋ช
์ด๋ ๋ฉํ ํ
์คํธ๋ฅผ ํฌํจํ์ง ๋ง์ธ์.
|
401 |
"""
|
402 |
|
403 |
def generate_prompt_with_gemini(product_name, background_info, additional_info=""):
|
@@ -409,14 +383,12 @@ def generate_prompt_with_gemini(product_name, background_info, additional_info="
|
|
409 |
try:
|
410 |
genai_generative.configure(api_key=GEMINI_API_KEY)
|
411 |
|
412 |
-
# ๋ ์์ธํ ํ๋กฌํํธ ์์ฒญ ํ
ํ๋ฆฟ
|
413 |
prompt_request = f"""
|
414 |
์ํ๋ช
: {product_name}
|
415 |
๋ฐฐ๊ฒฝ ์ ํ: {background_info.get('english', 'studio')}
|
416 |
๋ฐฐ๊ฒฝ ์นดํ
๊ณ ๋ฆฌ: {background_info.get('category', '')}
|
417 |
๋ฐฐ๊ฒฝ ์ด๋ฆ: {background_info.get('name', '')}
|
418 |
์ถ๊ฐ ์์ฒญ์ฌํญ: {additional_info}
|
419 |
-
|
420 |
์ค์ ์๊ตฌ์ฌํญ:
|
421 |
1. ์ํ(#1)์ด ์ด๋ฏธ์ง ๊ตฌ๋์์ ์ค์ฌ์ ์ธ ์์น๋ฅผ ์ฐจ์งํ๋ฉฐ ์ ์ ํ ํฌ๊ธฐ(์ด๋ฏธ์ง์ 60-70%)๋ก ํํ๋๋๋ก ํ๋กฌํํธ๋ฅผ ์์ฑํด์ฃผ์ธ์.
|
422 |
2. ์ด๋ฏธ์ง๋ ์ ํํ 1:1 ๋น์จ(์ ์ฌ๊ฐํ)์ด์ด์ผ ํฉ๋๋ค.
|
@@ -431,29 +403,25 @@ def generate_prompt_with_gemini(product_name, background_info, additional_info="
|
|
431 |
7. ์์ ๊ตฌ์ฑ(color palette, color harmonies)์ ๋ช
ํํ ํด์ฃผ์ธ์.
|
432 |
8. ๊ณ ๊ธ์ค๋ฌ์ด ์์
๊ด๊ณ ํ์ง์ ์ด๋ฏธ์ง๊ฐ ๋๋๋ก ํ๋กฌํํธ๋ฅผ ์์ฑํด์ฃผ์ธ์.
|
433 |
9. ํ๋กฌํํธ ๋์ ๋ฏธ๋์ ๋ ํ๋ผ๋ฏธํฐ "--ar 1:1 --s 750 --q 2 --v 5.2"๋ฅผ ์ถ๊ฐํด์ฃผ์ธ์.
|
434 |
-
|
435 |
ํ๊ตญ์ด ์
๋ ฅ ๋ด์ฉ์ ์ ๋ฌธ์ ์ธ ์์ด๋ก ๋ฒ์ญํ์ฌ ๋ฐ์ํด์ฃผ์ธ์.
|
436 |
"""
|
437 |
-
# ํฅ์๋ ์์คํ
์ธ์คํธ๋ญ์
์ฌ์ฉ
|
438 |
model = genai_generative.GenerativeModel(
|
439 |
'gemini-2.0-flash',
|
440 |
system_instruction=generate_enhanced_system_instruction()
|
441 |
)
|
442 |
|
443 |
-
# ๋ ์ฐฝ์์ ์ธ ๊ฒฐ๊ณผ๋ฅผ ์ํ ์์ฑ ์ค์ ์กฐ์
|
444 |
response = model.generate_content(
|
445 |
prompt_request,
|
446 |
generation_config=genai_generative.types.GenerationConfig(
|
447 |
-
temperature=0.8,
|
448 |
top_p=0.97,
|
449 |
top_k=64,
|
450 |
-
max_output_tokens=1600,
|
451 |
)
|
452 |
)
|
453 |
|
454 |
response_text = response.text.strip()
|
455 |
|
456 |
-
# ๋ฏธ๋์ ๋ ํ๋ผ๋ฏธํฐ๊ฐ ์์ ๊ฒฝ์ฐ ์ถ๊ฐ
|
457 |
if "--ar 1:1" not in response_text:
|
458 |
response_text = response_text.rstrip(".") + ". --ar 1:1 --s 750 --q 2 --v 5.2"
|
459 |
|
@@ -504,51 +472,34 @@ def generate_product_images(image, bg_type, simple, studio, nature, indoor, tech
|
|
504 |
result_img, status, _ = process_images_with_prompt(image, final_prompt, variation_index=i)
|
505 |
images_list.append(result_img)
|
506 |
statuses.append(f"์ด๋ฏธ์ง #{i+1}: {status}")
|
507 |
-
time.sleep(1)
|
508 |
combined_status = "\n".join(statuses)
|
509 |
return images_list[0], images_list[1], images_list[2], images_list[3], combined_status, final_prompt
|
510 |
|
511 |
# ------------------- Gradio ์ธํฐํ์ด์ค ๊ตฌ์ฑ -------------------
|
512 |
def create_app():
|
513 |
-
# ๋๋กญ๋ค์ด ์ต์
์ด๊ธฐํ
|
514 |
dropdown_options = initialize_dropdowns()
|
515 |
|
516 |
with gr.Blocks(title="๊ณ ๊ธ ์ํ ์ด๋ฏธ์ง ๋ฐฐ๊ฒฝ ํ๋กฌํํธ ๋ฐ ์ด๋ฏธ์ง ์์ฑ") as demo:
|
517 |
gr.Markdown("# ๊ณ ๊ธ ์ํ ์ด๋ฏธ์ง ๋ฐฐ๊ฒฝ ํ๋กฌํํธ ๋ฐ ์ด๋ฏธ์ง ์์ฑ")
|
518 |
gr.Markdown(
|
519 |
-
"์ํ ์ด๋ฏธ์ง๋ฅผ ์
๋ก๋ํ๊ณ ,
|
520 |
"๋จ์ผ ์ด๋ฏธ์ง ์์ฑ๊ณผ 4์ฅ ์ด๋ฏธ์ง ์์ฑ ๋ชจ๋ ๊ฐ๋ฅํฉ๋๋ค."
|
521 |
)
|
522 |
|
523 |
with gr.Row():
|
524 |
-
# API ํค ์
๋ ฅ
|
525 |
gemini_api_key = gr.Textbox(
|
526 |
label="Gemini API ํค",
|
527 |
type="password",
|
528 |
placeholder="API ํค๋ฅผ ์
๋ ฅํ์ธ์",
|
529 |
interactive=True
|
530 |
)
|
531 |
-
|
532 |
-
# API ํค ์ค์ ๋ฒํผ ์ถ๊ฐ
|
533 |
-
api_key_btn = gr.Button("API ํค ์ค์ ")
|
534 |
-
api_key_status = gr.Textbox(label="API ํค ์ํ", interactive=False)
|
535 |
-
|
536 |
-
def set_api_key(api_key):
|
537 |
-
os.environ["GEMINI_API_KEY"] = api_key
|
538 |
-
return "API ํค๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์ค์ ๋์์ต๋๋ค."
|
539 |
-
|
540 |
-
api_key_btn.click(
|
541 |
-
fn=set_api_key,
|
542 |
-
inputs=[gemini_api_key],
|
543 |
-
outputs=[api_key_status]
|
544 |
-
)
|
545 |
-
|
546 |
with gr.Row():
|
547 |
with gr.Column(scale=1):
|
548 |
product_name = gr.Textbox(label="์ํ๋ช
(ํ๊ตญ์ด ์
๋ ฅ)", placeholder="์: ์คํจ์ผ์ด ํ๋ธ, ์ค๋งํธ์์น, ํฅ์, ์ด๋ํ ๋ฑ", interactive=True)
|
549 |
-
# ์ํ ์ด๋ฏธ์ง ์
๋ก๋๋ฅผ ์ํ๋ช
์๋๋ก ์ด๋
|
550 |
image_input = gr.Image(label="์ํ ์ด๋ฏธ์ง ์
๋ก๋", type="pil")
|
551 |
-
|
552 |
background_type = gr.Radio(
|
553 |
choices=["์ฌํ ๋ฐฐ๊ฒฝ", "์คํ๋์ค ๋ฐฐ๊ฒฝ", "์์ฐ ํ๊ฒฝ", "์ค๋ด ํ๊ฒฝ", "ํ
ํฌ๋๋ก์ง ๋ฐฐ๊ฒฝ", "์ปฌ๋ฌํ ํจํด ๋ฐฐ๊ฒฝ", "์ถ์/ํน์ ๋ฐฐ๊ฒฝ", "์ฅฌ์ผ๋ฆฌ ๋ฐฐ๊ฒฝ"],
|
554 |
label="๋ฐฐ๊ฒฝ ์ ํ",
|
@@ -603,7 +554,6 @@ def create_app():
|
|
603 |
visible=False,
|
604 |
interactive=True
|
605 |
)
|
606 |
-
|
607 |
jewelry_dropdown = gr.Dropdown(
|
608 |
choices=dropdown_options["jewelry"],
|
609 |
value=dropdown_options["jewelry"][0] if dropdown_options["jewelry"] else None,
|
@@ -611,13 +561,13 @@ def create_app():
|
|
611 |
visible=False,
|
612 |
interactive=True
|
613 |
)
|
614 |
-
|
615 |
additional_info = gr.Textbox(
|
616 |
label="์ถ๊ฐ ์์ฒญ์ฌํญ (์ ํ์ฌํญ)",
|
617 |
placeholder="์: ๊ณ ๊ธ์ค๋ฌ์ด ๋๋, ๋ฐ์ ์กฐ๋ช
, ์์ฐ์ค๋ฌ์ด ๋ณด์กฐ ๊ฐ์ฒด ๋ฑ",
|
618 |
lines=3,
|
619 |
interactive=True
|
620 |
)
|
|
|
621 |
def update_dropdowns(bg_type):
|
622 |
return {
|
623 |
simple_dropdown: gr.update(visible=(bg_type == "์ฌํ ๋ฐฐ๊ฒฝ")),
|
@@ -640,47 +590,45 @@ def create_app():
|
|
640 |
multi_btn = gr.Button("ํ๋กฌํํธ ๋ฐ 4์ฅ ์ด๋ฏธ์ง ์์ฑ", variant="primary")
|
641 |
|
642 |
with gr.Column(scale=1):
|
643 |
-
#
|
644 |
-
prompt_output = gr.Textbox(label="์์ฑ๋ ํ๋กฌํํธ (์์ด)", lines=6)
|
645 |
-
|
646 |
-
# ์ด๋ฏธ์ง ๋ ์ด์์ ๋ณ๊ฒฝ: 2x2 ๊ทธ๋ฆฌ๋๋ก ๋ฐฐ์น
|
647 |
with gr.Row():
|
648 |
image_output1 = gr.Image(label="์ด๋ฏธ์ง #1", type="filepath")
|
649 |
image_output2 = gr.Image(label="์ด๋ฏธ์ง #2", type="filepath")
|
650 |
-
|
651 |
with gr.Row():
|
652 |
image_output3 = gr.Image(label="์ด๋ฏธ์ง #3", type="filepath")
|
653 |
image_output4 = gr.Image(label="์ด๋ฏธ์ง #4", type="filepath")
|
654 |
-
|
655 |
status_output = gr.Textbox(label="๊ฒฐ๊ณผ ์ ๋ณด", lines=3)
|
656 |
|
657 |
-
# ๋จ์ผ ์ด๋ฏธ์ง
|
658 |
-
def modified_single_image_gen(
|
659 |
-
|
660 |
-
result_img, status,
|
661 |
-
# ๋จ์ผ
|
662 |
-
return
|
663 |
|
664 |
single_btn.click(
|
665 |
fn=modified_single_image_gen,
|
666 |
-
inputs=[image_input, background_type, simple_dropdown, studio_dropdown, nature_dropdown, indoor_dropdown, tech_dropdown, colorful_dropdown, abstract_dropdown, jewelry_dropdown, product_name, additional_info],
|
667 |
-
outputs=[
|
668 |
)
|
669 |
|
|
|
|
|
|
|
|
|
|
|
|
|
670 |
multi_btn.click(
|
671 |
-
fn=
|
672 |
-
inputs=[image_input, background_type, simple_dropdown, studio_dropdown, nature_dropdown, indoor_dropdown, tech_dropdown, colorful_dropdown, abstract_dropdown, jewelry_dropdown, product_name, additional_info],
|
673 |
-
outputs=[image_output1, image_output2, image_output3, image_output4, status_output
|
674 |
)
|
675 |
|
676 |
return demo
|
677 |
|
678 |
# ------------------- ๋ฉ์ธ ์คํ ํจ์ -------------------
|
679 |
if __name__ == "__main__":
|
680 |
-
# ๋ฐฐ๊ฒฝ ์ต์
์ด๊ธฐํ - JSON ํ์ผ์์ ๋ก๋
|
681 |
initialize_backgrounds()
|
682 |
-
|
683 |
-
# ์ฑ ์์ฑ ๋ฐ ์คํ
|
684 |
app = create_app()
|
685 |
app.queue()
|
686 |
-
app.launch()
|
|
|
33 |
ABSTRACT_BACKGROUNDS = {}
|
34 |
JEWELRY_BACKGROUNDS = {} # ์ฅฌ์ผ๋ฆฌ ๋ฐฐ๊ฒฝ ์ ์ญ ๋ณ์ ์ถ๊ฐ
|
35 |
|
|
|
36 |
# ------------------- ๋ฐฐ๊ฒฝ JSON ํ์ผ ๋ก๋ ํจ์ -------------------
|
37 |
def load_background_json(filename):
|
38 |
"""๋ฐฐ๊ฒฝ JSON ํ์ผ ๋ก๋ ํจ์"""
|
|
|
55 |
global SIMPLE_BACKGROUNDS, STUDIO_BACKGROUNDS, NATURE_BACKGROUNDS, INDOOR_BACKGROUNDS
|
56 |
global TECHNOLOGY_BACKGROUNDS, COLORFUL_PATTERN_BACKGROUNDS, ABSTRACT_BACKGROUNDS
|
57 |
global JEWELRY_BACKGROUNDS # ์ฅฌ์ผ๋ฆฌ ๋ฐฐ๊ฒฝ ์ถ๊ฐ
|
|
|
58 |
|
|
|
59 |
logger.info(f"Backgrounds ๋๋ ํ ๋ฆฌ ๊ฒฝ๋ก: {BACKGROUNDS_DIR}")
|
60 |
logger.info(f"๋๋ ํ ๋ฆฌ ๋ด ํ์ผ ๋ชฉ๋ก: {os.listdir(BACKGROUNDS_DIR)}")
|
61 |
|
|
|
62 |
SIMPLE_BACKGROUNDS = load_background_json("simple_backgrounds.json")
|
63 |
STUDIO_BACKGROUNDS = load_background_json("studio_backgrounds.json")
|
64 |
NATURE_BACKGROUNDS = load_background_json("nature_backgrounds.json")
|
65 |
INDOOR_BACKGROUNDS = load_background_json("indoor_backgrounds.json")
|
66 |
+
TECHNOLOGY_BACKGROUNDS = load_background_json("tech-backgrounds-final.json")
|
67 |
+
COLORFUL_PATTERN_BACKGROUNDS = load_background_json("colorful-pattern-backgrounds.json")
|
68 |
ABSTRACT_BACKGROUNDS = load_background_json("abstract_backgrounds.json")
|
69 |
JEWELRY_BACKGROUNDS = load_background_json("jewelry_backgrounds.json")
|
|
|
70 |
|
71 |
# ๊ธฐ๋ณธ๊ฐ ์ค์ (ํ์ผ์ด ์๊ฑฐ๋ ๋น์ด์๋ ๊ฒฝ์ฐ)
|
72 |
if not SIMPLE_BACKGROUNDS:
|
|
|
88 |
|
89 |
logger.info("๋ชจ๋ ๋ฐฐ๊ฒฝ ์ต์
์ด๊ธฐํ ์๋ฃ")
|
90 |
|
91 |
+
# ๋ฐฐ๊ฒฝ ๋๋กญ๋ค์ด ์ด๊ธฐํ๋ฅผ ์ํ ํจ์
|
92 |
def initialize_dropdowns():
|
93 |
"""๋๋กญ๋ค์ด ๋ฉ๋ด ์ด๊ธฐํ ํจ์"""
|
|
|
94 |
simple_choices = list(SIMPLE_BACKGROUNDS.keys())
|
95 |
studio_choices = list(STUDIO_BACKGROUNDS.keys())
|
96 |
nature_choices = list(NATURE_BACKGROUNDS.keys())
|
|
|
99 |
colorful_choices = list(COLORFUL_PATTERN_BACKGROUNDS.keys())
|
100 |
abstract_choices = list(ABSTRACT_BACKGROUNDS.keys())
|
101 |
jewelry_choices = list(JEWELRY_BACKGROUNDS.keys())
|
|
|
|
|
102 |
|
103 |
return {
|
104 |
"simple": simple_choices,
|
|
|
108 |
"tech": tech_choices,
|
109 |
"colorful": colorful_choices,
|
110 |
"abstract": abstract_choices,
|
111 |
+
"jewelry": jewelry_choices,
|
112 |
}
|
113 |
|
|
|
114 |
# ------------------- ๊ธฐ๋ณธ ์ ํธ๋ฆฌํฐ ํจ์ -------------------
|
115 |
def save_binary_file(file_name, data):
|
116 |
with open(file_name, "wb") as f:
|
|
|
182 |
client = genai.Client(api_key=api_key)
|
183 |
logger.info(f"Gemini API ์์ฒญ ์์ - ํ๋กฌํํธ: {prompt}, ๋ณํ ์ธ๋ฑ์ค: {variation_index}")
|
184 |
|
|
|
185 |
variation_suffixes = [
|
186 |
" Create this as a professional studio product shot with precise focus on the product details. Do not add any text, watermarks, or labels to the image.",
|
187 |
" Create this as a high-contrast artistic studio shot with dramatic lighting and shadows. Do not add any text, watermarks, or labels to the image.",
|
|
|
200 |
contents.append(img)
|
201 |
logger.info(f"์ด๋ฏธ์ง #{idx} ์ถ๊ฐ๋จ")
|
202 |
|
|
|
203 |
response = client.models.generate_content(
|
204 |
model="gemini-2.0-flash-exp-image-generation",
|
205 |
contents=contents,
|
206 |
config=types.GenerateContentConfig(
|
207 |
response_modalities=['Text', 'Image'],
|
208 |
+
temperature=1.05,
|
209 |
+
top_p=0.97,
|
210 |
+
top_k=50,
|
211 |
+
max_output_tokens=10240
|
212 |
)
|
213 |
)
|
214 |
|
|
|
263 |
# ------------------- ํ๋กฌํํธ ๊ด๋ จ ํจ์ -------------------
|
264 |
def filter_prompt_only(prompt):
|
265 |
"""Gemini์ ์ค๋ช
๋ฐ ๋ถํ์ํ ๋ฉ์์ง๋ฅผ ์ ๊ฑฐํ๊ณ ์ค์ ํ๋กฌํํธ๋ง ์ถ์ถํ๋ ํจ์"""
|
|
|
|
|
266 |
code_block_pattern = r"```\s*(.*?)```"
|
267 |
code_match = re.search(code_block_pattern, prompt, re.DOTALL)
|
268 |
if code_match:
|
269 |
return code_match.group(1).strip()
|
270 |
|
|
|
271 |
if "--ar 1:1" in prompt:
|
272 |
lines = prompt.split('\n')
|
273 |
prompt_lines = []
|
274 |
in_prompt = False
|
|
|
275 |
for line in lines:
|
|
|
276 |
if (not in_prompt and
|
277 |
("product" in line.lower() or
|
278 |
"magazine" in line.lower() or
|
|
|
280 |
"photography" in line.lower())):
|
281 |
in_prompt = True
|
282 |
prompt_lines.append(line)
|
|
|
283 |
elif in_prompt:
|
|
|
284 |
if "explanation" in line.lower() or "let me know" in line.lower():
|
285 |
break
|
286 |
prompt_lines.append(line)
|
|
|
|
|
287 |
if prompt_lines:
|
288 |
return '\n'.join(prompt_lines).strip()
|
289 |
|
|
|
290 |
return prompt.strip()
|
291 |
|
292 |
def get_selected_background_info(bg_type, simple, studio, nature, indoor, tech, colorful, abstract, jewelry):
|
|
|
333 |
"name": abstract,
|
334 |
"english": ABSTRACT_BACKGROUNDS.get(abstract, "abstract background")
|
335 |
}
|
|
|
336 |
elif bg_type == "์ฅฌ์ผ๋ฆฌ ๋ฐฐ๊ฒฝ":
|
337 |
return {
|
338 |
"category": "์ฅฌ์ผ๋ฆฌ ๋ฐฐ๊ฒฝ",
|
339 |
"name": jewelry,
|
340 |
"english": JEWELRY_BACKGROUNDS.get(jewelry, "jewelry backdrop")
|
341 |
}
|
|
|
342 |
else:
|
343 |
return {
|
344 |
"category": "๊ธฐ๋ณธ ๋ฐฐ๊ฒฝ",
|
|
|
346 |
"english": "white background"
|
347 |
}
|
348 |
|
|
|
349 |
def generate_enhanced_system_instruction():
|
350 |
"""ํฅ์๋ ์์คํ
์ธ์คํธ๋ญ์
์์ฑ ํจ์"""
|
351 |
return """๋น์ ์ ์ํ ์ด๋ฏธ์ง์ ๋ฐฐ๊ฒฝ์ ๋ณ๊ฒฝํ๊ธฐ ์ํ ์ต๊ณ ํ์ง์ ํ๋กฌํํธ๋ฅผ ์์ฑํ๋ ์ ๋ฌธ๊ฐ์
๋๋ค.
|
352 |
์ฌ์ฉ์๊ฐ ์ ๊ณตํ๋ ์ํ๋ช
, ๋ฐฐ๊ฒฝ ์ ํ, ์ถ๊ฐ ์์ฒญ์ฌํญ์ ๋ฐํ์ผ๋ก ๋ฏธ๋์ ๋(Midjourney)์ ์ฌ์ฉํ ์ ์๋ ์์ธํ๊ณ ์ ๋ฌธ์ ์ธ ํ๋กฌํํธ๋ฅผ ์์ด๋ก ์์ฑํด์ฃผ์ธ์.
|
|
|
353 |
๋ค์ ๊ฐ์ด๋๋ผ์ธ์ ๋ฐ๋์ ์ค์ํด์ผ ํฉ๋๋ค:
|
|
|
354 |
1. ์ํ์ "#1"๋ก ์ง์ ํ์ฌ ์ฐธ์กฐํฉ๋๋ค. (์: "skincare tube (#1)")
|
355 |
2. *** ๋งค์ฐ ์ค์: ์ํ์ ์๋ ํน์ฑ(๋์์ธ, ์์, ํํ, ๋ก๊ณ , ํจํค์ง ๋ฑ)์ ์ด๋ค ์ํฉ์์๋ ์ ๋ ๋ณ๊ฒฝํ์ง ์์ต๋๋ค. ***
|
356 |
3. *** ์ํ์ ๋ณธ์ง์ ํน์ฑ์ ์ ์งํ๋, ์ํ์ ํฌ์ปค์ค๋ฅผ ๋ง์ถฐ ๋ชจ๋ ์ธ๋ถ ์ฌํญ์ด ์ ๋ช
ํ๊ฒ ๋๋ฌ๋๋๋ก ํ๋ฉฐ,
|
|
|
370 |
- "ultra high definition"
|
371 |
- "crystal clear details"
|
372 |
10. ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ๊ตฌ์ฒด์ ์ธ ๋ฐฐ๊ฒฝ๊ณผ ์ถ๊ฐ ์์ฒญ์ฌํญ์ ํ๋กฌํํธ์ ์ ํํ ๋ฐ์ํ๊ณ ํ์ฅํฉ๋๋ค.
|
373 |
+
11. ํ๋กฌํํธ ๋์ ๋ฏธ๋์ ๋ ํ๋ผ๋ฏธํฐ "--ar 1:1 --s 750 --q 2 --v 5.2" ํ๋ผ๋ฏธํฐ๋ฅผ ์ถ๊ฐํ์ฌ ๋ฏธ๋์ ๋์์ ๊ณ ํ์ง ์ ์ฌ๊ฐํ ๋น์จ์ ๊ฐ์ ํฉ๋๋ค.
|
374 |
+
12. ๋งค์ฐ ์ค์: ํ๋กฌํํธ ์ธ์ ๋ค๋ฅธ ์ค๋ช
์ด๋ ๋ฉํ ํ
์คํธ๋ฅผ ํฌํจํ์ง ๋ง์ธ์. ์ค์ง ํ๋กฌํํธ ์์ฒด๋ง ์ ๊ณตํ์ธ์.
|
375 |
"""
|
376 |
|
377 |
def generate_prompt_with_gemini(product_name, background_info, additional_info=""):
|
|
|
383 |
try:
|
384 |
genai_generative.configure(api_key=GEMINI_API_KEY)
|
385 |
|
|
|
386 |
prompt_request = f"""
|
387 |
์ํ๋ช
: {product_name}
|
388 |
๋ฐฐ๊ฒฝ ์ ํ: {background_info.get('english', 'studio')}
|
389 |
๋ฐฐ๊ฒฝ ์นดํ
๊ณ ๋ฆฌ: {background_info.get('category', '')}
|
390 |
๋ฐฐ๊ฒฝ ์ด๋ฆ: {background_info.get('name', '')}
|
391 |
์ถ๊ฐ ์์ฒญ์ฌํญ: {additional_info}
|
|
|
392 |
์ค์ ์๊ตฌ์ฌํญ:
|
393 |
1. ์ํ(#1)์ด ์ด๋ฏธ์ง ๊ตฌ๋์์ ์ค์ฌ์ ์ธ ์์น๋ฅผ ์ฐจ์งํ๋ฉฐ ์ ์ ํ ํฌ๊ธฐ(์ด๋ฏธ์ง์ 60-70%)๋ก ํํ๋๋๋ก ํ๋กฌํํธ๋ฅผ ์์ฑํด์ฃผ์ธ์.
|
394 |
2. ์ด๋ฏธ์ง๋ ์ ํํ 1:1 ๋น์จ(์ ์ฌ๊ฐํ)์ด์ด์ผ ํฉ๋๋ค.
|
|
|
403 |
7. ์์ ๊ตฌ์ฑ(color palette, color harmonies)์ ๋ช
ํํ ํด์ฃผ์ธ์.
|
404 |
8. ๊ณ ๊ธ์ค๋ฌ์ด ์์
๊ด๊ณ ํ์ง์ ์ด๋ฏธ์ง๊ฐ ๋๋๋ก ํ๋กฌํํธ๋ฅผ ์์ฑํด์ฃผ์ธ์.
|
405 |
9. ํ๋กฌํํธ ๋์ ๋ฏธ๋์ ๋ ํ๋ผ๋ฏธํฐ "--ar 1:1 --s 750 --q 2 --v 5.2"๋ฅผ ์ถ๊ฐํด์ฃผ์ธ์.
|
|
|
406 |
ํ๊ตญ์ด ์
๋ ฅ ๋ด์ฉ์ ์ ๋ฌธ์ ์ธ ์์ด๋ก ๋ฒ์ญํ์ฌ ๋ฐ์ํด์ฃผ์ธ์.
|
407 |
"""
|
|
|
408 |
model = genai_generative.GenerativeModel(
|
409 |
'gemini-2.0-flash',
|
410 |
system_instruction=generate_enhanced_system_instruction()
|
411 |
)
|
412 |
|
|
|
413 |
response = model.generate_content(
|
414 |
prompt_request,
|
415 |
generation_config=genai_generative.types.GenerationConfig(
|
416 |
+
temperature=0.8,
|
417 |
top_p=0.97,
|
418 |
top_k=64,
|
419 |
+
max_output_tokens=1600,
|
420 |
)
|
421 |
)
|
422 |
|
423 |
response_text = response.text.strip()
|
424 |
|
|
|
425 |
if "--ar 1:1" not in response_text:
|
426 |
response_text = response_text.rstrip(".") + ". --ar 1:1 --s 750 --q 2 --v 5.2"
|
427 |
|
|
|
472 |
result_img, status, _ = process_images_with_prompt(image, final_prompt, variation_index=i)
|
473 |
images_list.append(result_img)
|
474 |
statuses.append(f"์ด๋ฏธ์ง #{i+1}: {status}")
|
475 |
+
time.sleep(1)
|
476 |
combined_status = "\n".join(statuses)
|
477 |
return images_list[0], images_list[1], images_list[2], images_list[3], combined_status, final_prompt
|
478 |
|
479 |
# ------------------- Gradio ์ธํฐํ์ด์ค ๊ตฌ์ฑ -------------------
|
480 |
def create_app():
|
|
|
481 |
dropdown_options = initialize_dropdowns()
|
482 |
|
483 |
with gr.Blocks(title="๊ณ ๊ธ ์ํ ์ด๋ฏธ์ง ๋ฐฐ๊ฒฝ ํ๋กฌํํธ ๋ฐ ์ด๋ฏธ์ง ์์ฑ") as demo:
|
484 |
gr.Markdown("# ๊ณ ๊ธ ์ํ ์ด๋ฏธ์ง ๋ฐฐ๊ฒฝ ํ๋กฌํํธ ๋ฐ ์ด๋ฏธ์ง ์์ฑ")
|
485 |
gr.Markdown(
|
486 |
+
"์ํ ์ด๋ฏธ์ง๋ฅผ ์
๋ก๋ํ๊ณ , ์ํ๋ช
, ๋ฐฐ๊ฒฝ ์ต์
, ์ถ๊ฐ ์์ฒญ์ฌํญ ๋ฐ Gemini API ํค๋ฅผ ์
๋ ฅํ๋ฉด Gemini API๋ฅผ ํตํด ์์ด ํ๋กฌํํธ๋ฅผ ์์ฑํ๊ณ , ํด๋น ํ๋กฌํํธ๋ก ์ด๋ฏธ์ง๊ฐ ์์ฑ๋ฉ๋๋ค.\n\n"
|
487 |
"๋จ์ผ ์ด๋ฏธ์ง ์์ฑ๊ณผ 4์ฅ ์ด๋ฏธ์ง ์์ฑ ๋ชจ๋ ๊ฐ๋ฅํฉ๋๋ค."
|
488 |
)
|
489 |
|
490 |
with gr.Row():
|
491 |
+
# API ํค ์
๋ ฅ ํ๋๋ง ํ์ (API ํค ์ํ, ์ค์ ๋ฒํผ ์ ๊ฑฐ)
|
492 |
gemini_api_key = gr.Textbox(
|
493 |
label="Gemini API ํค",
|
494 |
type="password",
|
495 |
placeholder="API ํค๋ฅผ ์
๋ ฅํ์ธ์",
|
496 |
interactive=True
|
497 |
)
|
498 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
499 |
with gr.Row():
|
500 |
with gr.Column(scale=1):
|
501 |
product_name = gr.Textbox(label="์ํ๋ช
(ํ๊ตญ์ด ์
๋ ฅ)", placeholder="์: ์คํจ์ผ์ด ํ๋ธ, ์ค๋งํธ์์น, ํฅ์, ์ด๋ํ ๋ฑ", interactive=True)
|
|
|
502 |
image_input = gr.Image(label="์ํ ์ด๋ฏธ์ง ์
๋ก๋", type="pil")
|
|
|
503 |
background_type = gr.Radio(
|
504 |
choices=["์ฌํ ๋ฐฐ๊ฒฝ", "์คํ๋์ค ๋ฐฐ๊ฒฝ", "์์ฐ ํ๊ฒฝ", "์ค๋ด ํ๊ฒฝ", "ํ
ํฌ๋๋ก์ง ๋ฐฐ๊ฒฝ", "์ปฌ๋ฌํ ํจํด ๋ฐฐ๊ฒฝ", "์ถ์/ํน์ ๋ฐฐ๊ฒฝ", "์ฅฌ์ผ๋ฆฌ ๋ฐฐ๊ฒฝ"],
|
505 |
label="๋ฐฐ๊ฒฝ ์ ํ",
|
|
|
554 |
visible=False,
|
555 |
interactive=True
|
556 |
)
|
|
|
557 |
jewelry_dropdown = gr.Dropdown(
|
558 |
choices=dropdown_options["jewelry"],
|
559 |
value=dropdown_options["jewelry"][0] if dropdown_options["jewelry"] else None,
|
|
|
561 |
visible=False,
|
562 |
interactive=True
|
563 |
)
|
|
|
564 |
additional_info = gr.Textbox(
|
565 |
label="์ถ๊ฐ ์์ฒญ์ฌํญ (์ ํ์ฌํญ)",
|
566 |
placeholder="์: ๊ณ ๊ธ์ค๋ฌ์ด ๋๋, ๋ฐ์ ์กฐ๋ช
, ์์ฐ์ค๋ฌ์ด ๋ณด์กฐ ๊ฐ์ฒด ๋ฑ",
|
567 |
lines=3,
|
568 |
interactive=True
|
569 |
)
|
570 |
+
|
571 |
def update_dropdowns(bg_type):
|
572 |
return {
|
573 |
simple_dropdown: gr.update(visible=(bg_type == "์ฌํ ๋ฐฐ๊ฒฝ")),
|
|
|
590 |
multi_btn = gr.Button("ํ๋กฌํํธ ๋ฐ 4์ฅ ์ด๋ฏธ์ง ์์ฑ", variant="primary")
|
591 |
|
592 |
with gr.Column(scale=1):
|
593 |
+
# ํ๋กฌํํธ ์ถ๋ ฅ UI ์ ๊ฑฐ, ์ด๋ฏธ์ง 4์ฅ๋ง ์ถ๋ ฅ
|
|
|
|
|
|
|
594 |
with gr.Row():
|
595 |
image_output1 = gr.Image(label="์ด๋ฏธ์ง #1", type="filepath")
|
596 |
image_output2 = gr.Image(label="์ด๋ฏธ์ง #2", type="filepath")
|
|
|
597 |
with gr.Row():
|
598 |
image_output3 = gr.Image(label="์ด๋ฏธ์ง #3", type="filepath")
|
599 |
image_output4 = gr.Image(label="์ด๋ฏธ์ง #4", type="filepath")
|
|
|
600 |
status_output = gr.Textbox(label="๊ฒฐ๊ณผ ์ ๋ณด", lines=3)
|
601 |
|
602 |
+
# ๋จ์ผ ์ด๋ฏธ์ง ์์ฑ์ ์ํ ํจ์ (API ํค ์
๋ ฅ๊ฐ ํ์ฉ)
|
603 |
+
def modified_single_image_gen(api_key, image, bg_type, simple, studio, nature, indoor, tech, colorful, abstract, jewelry, product_name, additional_info):
|
604 |
+
os.environ["GEMINI_API_KEY"] = api_key.strip()
|
605 |
+
result_img, status, _ = generate_product_image(image, bg_type, simple, studio, nature, indoor, tech, colorful, abstract, jewelry, product_name, additional_info)
|
606 |
+
# ๋จ์ผ ์ด๋ฏธ์ง๋ ์ฒซ ๋ฒ์งธ ์ฌ๋กฏ์ ๋ฐฐ์น, ๋๋จธ์ง๋ None ๋ฐํ
|
607 |
+
return result_img, None, None, None, status
|
608 |
|
609 |
single_btn.click(
|
610 |
fn=modified_single_image_gen,
|
611 |
+
inputs=[gemini_api_key, image_input, background_type, simple_dropdown, studio_dropdown, nature_dropdown, indoor_dropdown, tech_dropdown, colorful_dropdown, abstract_dropdown, jewelry_dropdown, product_name, additional_info],
|
612 |
+
outputs=[image_output1, image_output2, image_output3, image_output4, status_output]
|
613 |
)
|
614 |
|
615 |
+
# 4์ฅ ์ด๋ฏธ์ง ์์ฑ์ ์ํ ํจ์ (API ํค ์
๋ ฅ๊ฐ ํ์ฉ)
|
616 |
+
def modified_multi_image_gen(api_key, image, bg_type, simple, studio, nature, indoor, tech, colorful, abstract, jewelry, product_name, additional_info):
|
617 |
+
os.environ["GEMINI_API_KEY"] = api_key.strip()
|
618 |
+
img1, img2, img3, img4, status, _ = generate_product_images(image, bg_type, simple, studio, nature, indoor, tech, colorful, abstract, jewelry, product_name, additional_info)
|
619 |
+
return img1, img2, img3, img4, status
|
620 |
+
|
621 |
multi_btn.click(
|
622 |
+
fn=modified_multi_image_gen,
|
623 |
+
inputs=[gemini_api_key, image_input, background_type, simple_dropdown, studio_dropdown, nature_dropdown, indoor_dropdown, tech_dropdown, colorful_dropdown, abstract_dropdown, jewelry_dropdown, product_name, additional_info],
|
624 |
+
outputs=[image_output1, image_output2, image_output3, image_output4, status_output]
|
625 |
)
|
626 |
|
627 |
return demo
|
628 |
|
629 |
# ------------------- ๋ฉ์ธ ์คํ ํจ์ -------------------
|
630 |
if __name__ == "__main__":
|
|
|
631 |
initialize_backgrounds()
|
|
|
|
|
632 |
app = create_app()
|
633 |
app.queue()
|
634 |
+
app.launch()
|