Update app.py
Browse files
app.py
CHANGED
@@ -26,7 +26,6 @@ def preprocess_prompt(prompt, image1, image2, image3):
|
|
26 |
"""
|
27 |
ํ๋กฌํํธ๋ฅผ ์ฒ๋ฆฌํ๊ณ ๊ธฐ๋ฅ ๋ช
๋ น์ ํด์
|
28 |
"""
|
29 |
-
# ๊ธฐ์กด preprocess_prompt ํจ์ ์ฝ๋ ์ ์ง
|
30 |
# ์ด๋ฏธ์ง ์๋ ์ฐธ์กฐ ํ์ธ ๋ฐ ์ฒ๋ฆฌ
|
31 |
has_img1 = image1 is not None
|
32 |
has_img2 = image2 is not None
|
@@ -48,9 +47,8 @@ def preprocess_prompt(prompt, image1, image2, image3):
|
|
48 |
else:
|
49 |
prompt = prompt.replace("#3", "์ธ ๋ฒ์งธ ์ด๋ฏธ์ง")
|
50 |
|
51 |
-
# ๊ธฐ๋ฅ ๋ช
๋ น ํด์
|
52 |
if "1. ์ด๋ฏธ์ง ๋ณ๊ฒฝ" in prompt:
|
53 |
-
# ์ค๋ช
์ถ์ถ์ ์๋ํ์ง๋ง ์คํจํด๋ ๊ธฐ๋ณธ ํ๋กฌํํธ ์ ๊ณต
|
54 |
desc_match = re.search(r'#1์ "(.*?)"์ผ๋ก ๋ฐ๊ฟ๋ผ', prompt)
|
55 |
if desc_match:
|
56 |
description = desc_match.group(1)
|
@@ -59,7 +57,6 @@ def preprocess_prompt(prompt, image1, image2, image3):
|
|
59 |
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง๋ฅผ ์ฐฝ์์ ์ผ๋ก ๋ณํํด์ฃผ์ธ์. ๋ ์์ํ๊ณ ์์ ์ ์ธ ๋ฒ์ ์ผ๋ก ๋ง๋ค์ด์ฃผ์ธ์."
|
60 |
|
61 |
elif "2. ๊ธ์์ง์ฐ๊ธฐ" in prompt:
|
62 |
-
# ์ง์ธ ํ
์คํธ ์ถ์ถ์ ์๋ํ์ง๋ง ์คํจํด๋ ๊ธฐ๋ณธ ํ๋กฌํํธ ์ ๊ณต
|
63 |
text_match = re.search(r'#1์์ "(.*?)"๋ฅผ ์ง์๋ผ', prompt)
|
64 |
if text_match:
|
65 |
text_to_remove = text_match.group(1)
|
@@ -71,7 +68,6 @@ def preprocess_prompt(prompt, image1, image2, image3):
|
|
71 |
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์ธ๋ฌผ ์ผ๊ตด์ ๋ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์ผ๊ตด๋ก ์์ฐ์ค๋ฝ๊ฒ ๊ต์ฒดํด์ฃผ์ธ์. ์ผ๊ตด์ ํ์ ๊ณผ ํน์ง์ ๋ ๋ฒ์งธ ์ด๋ฏธ์ง๋ฅผ ๋ฐ๋ฅด๋, ๋๋จธ์ง ๋ถ๋ถ์ ์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง๋ฅผ ์ ์งํด์ฃผ์ธ์."
|
72 |
|
73 |
elif "4. ์ท๋ฐ๊พธ๊ธฐ" in prompt:
|
74 |
-
# ์ฌ๋ฌ ์ด๋ฏธ์ง ์ฐธ์กฐ ์ฒ๋ฆฌ
|
75 |
if "#3" in prompt or "๋๋ #3" in prompt:
|
76 |
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์ธ๋ฌผ ์์์ ๋ ๋ฒ์งธ ๋๋ ์ธ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์์์ผ๋ก ์์ฐ์ค๋ฝ๊ฒ ๊ต์ฒดํด์ฃผ์ธ์. ์์์ ์คํ์ผ๊ณผ ์์์ ์ฐธ์กฐ ์ด๋ฏธ์ง๋ฅผ ๋ฐ๋ฅด๋, ์ ์ฒด ๋น์จ๊ณผ ํฌ์ฆ๋ ์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง๋ฅผ ์ ์งํด์ฃผ์ธ์."
|
77 |
else:
|
@@ -81,7 +77,6 @@ def preprocess_prompt(prompt, image1, image2, image3):
|
|
81 |
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ๋ฐฐ๊ฒฝ์ ๋ ๋ฒ์งธ ์ด๋ฏธ์ง์ ๋ฐฐ๊ฒฝ์ผ๋ก ์์ฐ์ค๋ฝ๊ฒ ๊ต์ฒดํด์ฃผ์ธ์. ์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์ฃผ์ ํผ์ฌ์ฒด๋ ์ ์งํ๊ณ , ๋ ๋ฒ์งธ ์ด๋ฏธ์ง์ ๋ฐฐ๊ฒฝ๊ณผ ์กฐํ๋กญ๊ฒ ํฉ์ฑํด์ฃผ์ธ์."
|
82 |
|
83 |
elif "6. ์ด๋ฏธ์ง ํฉ์ฑ(์ํํฌํจ)" in prompt:
|
84 |
-
# ์ฌ๋ฌ ์ด๋ฏธ์ง ์ฐธ์กฐ ์ฒ๋ฆฌ
|
85 |
if "#3" in prompt or "๋๋ #3" in prompt:
|
86 |
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ๋ ๋ฒ์งธ, ์ธ ๋ฒ์งธ ์ด๋ฏธ์ง๋ฅผ ์์ฐ์ค๋ฝ๊ฒ ํฉ์ฑํด์ฃผ์ธ์. ๋ชจ๋ ์ด๋ฏธ์ง์ ์ฃผ์ ์์๋ฅผ ํฌํจํ๊ณ , ํนํ ์ํ์ด ์ ๋ณด์ด๋๋ก ์กฐํ๋กญ๊ฒ ํตํฉํด์ฃผ์ธ์."
|
87 |
else:
|
@@ -90,11 +85,9 @@ def preprocess_prompt(prompt, image1, image2, image3):
|
|
90 |
elif "7. ์ด๋ฏธ์ง ํฉ์ฑ(์คํ์ผ์ ์ฉ)" in prompt:
|
91 |
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ๋ด์ฉ์ ๋ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์คํ์ผ๋ก ๋ณํํด์ฃผ์ธ์. ์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์ฃผ์ ํผ์ฌ์ฒด์ ๊ตฌ๋๋ ์ ์งํ๋, ๋ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์์ ์ ์คํ์ผ, ์์, ์ง๊ฐ์ ์ ์ฉํด์ฃผ์ธ์."
|
92 |
|
93 |
-
# ๊ฐ๋จํ ์์ ๋ณ๊ฒฝ ์์ฒญ ์ฒ๋ฆฌ
|
94 |
elif "์ ๋ถ์์์ผ๋ก ๋ฐ๊ฟ๋ผ" in prompt or "๋ฅผ ๋ถ์์์ผ๋ก ๋ฐ๊ฟ๋ผ" in prompt:
|
95 |
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง๋ฅผ ๋ถ์์ ํค์ผ๋ก ๋ณ๊ฒฝํด์ฃผ์ธ์. ์ ์ฒด์ ์ธ ์์์ ๋ถ์ ๊ณ์ด๋ก ์กฐ์ ํ๊ณ ์์ฐ์ค๋ฌ์ด ๋๋์ ์ ์งํด์ฃผ์ธ์."
|
96 |
|
97 |
-
# ๋ช
ํํ ์ด๋ฏธ์ง ์์ฑ ์์ฒญ ์ถ๊ฐ
|
98 |
prompt += " ์ด๋ฏธ์ง๋ฅผ ์์ฑํด์ฃผ์ธ์."
|
99 |
|
100 |
return prompt
|
@@ -104,29 +97,22 @@ def generate_with_images(prompt, images):
|
|
104 |
๊ณต์ ๋ฌธ์์ ๊ธฐ๋ฐํ ์ฌ๋ฐ๋ฅธ API ํธ์ถ ๋ฐฉ์ ๊ตฌํ
|
105 |
"""
|
106 |
try:
|
107 |
-
# API ํค ํ์ธ
|
108 |
api_key = os.environ.get("GEMINI_API_KEY")
|
109 |
if not api_key:
|
110 |
return None, "API ํค๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค. ํ๊ฒฝ๋ณ์๋ฅผ ํ์ธํด์ฃผ์ธ์."
|
111 |
|
112 |
-
# Gemini ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
|
113 |
client = genai.Client(api_key=api_key)
|
114 |
|
115 |
logger.info(f"Gemini API ์์ฒญ ์์ - ํ๋กฌํํธ: {prompt}")
|
116 |
|
117 |
-
# ์ปจํ
์ธ ์ค๋น
|
118 |
contents = []
|
119 |
-
|
120 |
-
# ํ
์คํธ ํ๋กฌํํธ ์ถ๊ฐ
|
121 |
contents.append(prompt)
|
122 |
|
123 |
-
# ์ด๋ฏธ์ง ์ถ๊ฐ
|
124 |
for idx, img in enumerate(images, 1):
|
125 |
if img is not None:
|
126 |
contents.append(img)
|
127 |
logger.info(f"์ด๋ฏธ์ง #{idx} ์ถ๊ฐ๋จ")
|
128 |
|
129 |
-
# ์์ฑ ์ค์ - ๊ณต์ ๋ฌธ์์ ๋ฐ๋ผ responseModalities ์ค์
|
130 |
response = client.models.generate_content(
|
131 |
model="gemini-2.0-flash-exp-image-generation",
|
132 |
contents=contents,
|
@@ -139,14 +125,12 @@ def generate_with_images(prompt, images):
|
|
139 |
)
|
140 |
)
|
141 |
|
142 |
-
# ์์ ํ์ผ ์์ฑ
|
143 |
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp:
|
144 |
temp_path = tmp.name
|
145 |
|
146 |
result_text = ""
|
147 |
image_found = False
|
148 |
|
149 |
-
# ์๋ต ์ฒ๋ฆฌ
|
150 |
for part in response.candidates[0].content.parts:
|
151 |
if hasattr(part, 'text') and part.text:
|
152 |
result_text += part.text
|
@@ -159,7 +143,6 @@ def generate_with_images(prompt, images):
|
|
159 |
if not image_found:
|
160 |
return None, f"API์์ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ์ง ๋ชปํ์ต๋๋ค. ์๋ต ํ
์คํธ: {result_text}"
|
161 |
|
162 |
-
# ๊ฒฐ๊ณผ ์ด๋ฏธ์ง ๋ฐํ
|
163 |
result_img = Image.open(temp_path)
|
164 |
if result_img.mode == "RGBA":
|
165 |
result_img = result_img.convert("RGB")
|
@@ -175,16 +158,13 @@ def process_images_with_prompt(image1, image2, image3, prompt):
|
|
175 |
3๊ฐ์ ์ด๋ฏธ์ง์ ํ๋กฌํํธ๋ฅผ ์ฒ๋ฆฌํ๋ ํจ์
|
176 |
"""
|
177 |
try:
|
178 |
-
# ์ด๋ฏธ์ง ๊ฐ์ ํ์ธ
|
179 |
images = [image1, image2, image3]
|
180 |
valid_images = [img for img in images if img is not None]
|
181 |
|
182 |
if not valid_images:
|
183 |
return None, "์ ์ด๋ ํ๋์ ์ด๋ฏธ์ง๋ฅผ ์
๋ก๋ํด์ฃผ์ธ์."
|
184 |
|
185 |
-
# ํ๋กฌํํธ ์ฒ๋ฆฌ
|
186 |
if not prompt or not prompt.strip():
|
187 |
-
# ํ๋กฌํํธ๊ฐ ์์ผ๋ฉด ์
๋ก๋๋ ์ด๋ฏธ์ง ์์ ๋ฐ๋ผ ์๋ ํฉ์ฑ ํ๋กฌํํธ๋ฅผ ์์ด๋ก ์์ฑ
|
188 |
if len(valid_images) == 1:
|
189 |
prompt = "Please creatively transform this image into a more vivid and artistic version."
|
190 |
logger.info("Default prompt generated for single image")
|
@@ -195,17 +175,36 @@ def process_images_with_prompt(image1, image2, image3, prompt):
|
|
195 |
prompt = "Please creatively composite these three images, combining their main elements into a cohesive and natural scene."
|
196 |
logger.info("Default prompt generated for three images")
|
197 |
else:
|
198 |
-
# ํ๋กฌํํธ ์ ์ฒ๋ฆฌ ๋ฐ ๊ธฐ๋ฅ ๋ช
๋ น ํด์
|
199 |
prompt = preprocess_prompt(prompt, image1, image2, image3)
|
200 |
|
201 |
-
# ์๋ก์ด API ํธ์ถ ๋ฐฉ์ ์ฌ์ฉ
|
202 |
return generate_with_images(prompt, valid_images)
|
203 |
|
204 |
except Exception as e:
|
205 |
logger.exception("์ด๋ฏธ์ง ์ฒ๋ฆฌ ์ค ์ค๋ฅ ๋ฐ์:")
|
206 |
return None, f"์ค๋ฅ ๋ฐ์: {str(e)}"
|
207 |
|
208 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
|
210 |
# Gradio ์ธํฐํ์ด์ค
|
211 |
with gr.Blocks() as demo:
|
@@ -233,44 +232,38 @@ with gr.Blocks() as demo:
|
|
233 |
label="ํ๋กฌํํธ (์ ํ ์ฌํญ)"
|
234 |
)
|
235 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
# ์์ฑ ๋ฒํผ
|
237 |
submit_btn = gr.Button("์ด๋ฏธ์ง ์์ฑ", variant="primary")
|
238 |
|
239 |
with gr.Column():
|
240 |
-
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
|
241 |
output_image = gr.Image(label="์์ฑ๋ ์ด๋ฏธ์ง")
|
242 |
output_text = gr.Textbox(label="์ํ ๋ฉ์์ง")
|
243 |
-
|
244 |
-
# ์ฌ์ฉ๋ ํ๋กฌํํธ ํ์
|
245 |
prompt_display = gr.Textbox(label="์ฌ์ฉ๋ ํ๋กฌํํธ", visible=True)
|
246 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
247 |
# ์ด๋ฏธ์ง ์์ฑ ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ
|
248 |
-
def process_and_show_prompt(image1, image2, image3, prompt):
|
249 |
-
# ์ด๋ฏธ์ง ๊ฐ์ ํ์ธ
|
250 |
-
images = [image1, image2, image3]
|
251 |
-
valid_images = [img for img in images if img is not None]
|
252 |
-
|
253 |
-
try:
|
254 |
-
# ์๋ ํ๋กฌํํธ ์์ฑ ๋๋ ํ๋กฌํํธ ์ ์ฒ๋ฆฌ
|
255 |
-
auto_prompt = prompt
|
256 |
-
if not prompt or not prompt.strip():
|
257 |
-
if len(valid_images) == 1:
|
258 |
-
auto_prompt = "Please creatively transform this image into a more vivid and artistic version."
|
259 |
-
elif len(valid_images) == 2:
|
260 |
-
auto_prompt = "Please seamlessly composite these two images, integrating their key elements harmoniously into a single image."
|
261 |
-
else:
|
262 |
-
auto_prompt = "Please creatively composite these three images, combining their main elements into a cohesive and natural scene."
|
263 |
-
else:
|
264 |
-
auto_prompt = preprocess_prompt(prompt, image1, image2, image3)
|
265 |
-
|
266 |
-
# ์ด๋ฏธ์ง ์์ฑ ํจ์ ํธ์ถ
|
267 |
-
result_img, status = process_images_with_prompt(image1, image2, image3, prompt)
|
268 |
-
|
269 |
-
return result_img, status, auto_prompt
|
270 |
-
except Exception as e:
|
271 |
-
logger.exception("์ฒ๋ฆฌ ์ค ์ค๋ฅ ๋ฐ์:")
|
272 |
-
return None, f"์ค๋ฅ ๋ฐ์: {str(e)}", prompt
|
273 |
-
|
274 |
submit_btn.click(
|
275 |
fn=process_and_show_prompt,
|
276 |
inputs=[image1_input, image2_input, image3_input, prompt_input],
|
@@ -284,11 +277,11 @@ with gr.Blocks() as demo:
|
|
284 |
1. **์๋ ํฉ์ฑ**: ์ด๋ฏธ์ง๋ง ์
๋ก๋ํ๊ณ ํ๋กฌํํธ๋ฅผ ๋น์๋๋ฉด ์๋์ผ๋ก ํฉ์ฑ๋ฉ๋๋ค.
|
285 |
2. **์ด๋ฏธ์ง ์ฐธ์กฐ**: #1, #2, #3์ผ๋ก ๊ฐ ์ด๋ฏธ์ง๋ฅผ ์ฐธ์กฐํ ์ ์์ต๋๋ค.
|
286 |
3. **์ผ๋ถ ์ด๋ฏธ์ง๋ง**: ํ์ํ ์ด๋ฏธ์ง๋ง ์
๋ก๋ํด๋ ๊ธฐ๋ฅ ์คํ์ด ๊ฐ๋ฅํฉ๋๋ค.
|
|
|
287 |
|
288 |
> **ํ**: ํ๋กฌํํธ๋ฅผ ์ง์ ์์ ํ ์๋ ์์ต๋๋ค.
|
289 |
"""
|
290 |
)
|
291 |
|
292 |
-
# ์ ํ๋ฆฌ์ผ์ด์
์คํ
|
293 |
if __name__ == "__main__":
|
294 |
demo.launch(share=True)
|
|
|
26 |
"""
|
27 |
ํ๋กฌํํธ๋ฅผ ์ฒ๋ฆฌํ๊ณ ๊ธฐ๋ฅ ๋ช
๋ น์ ํด์
|
28 |
"""
|
|
|
29 |
# ์ด๋ฏธ์ง ์๋ ์ฐธ์กฐ ํ์ธ ๋ฐ ์ฒ๋ฆฌ
|
30 |
has_img1 = image1 is not None
|
31 |
has_img2 = image2 is not None
|
|
|
47 |
else:
|
48 |
prompt = prompt.replace("#3", "์ธ ๋ฒ์งธ ์ด๋ฏธ์ง")
|
49 |
|
50 |
+
# ๊ธฐ๋ฅ ๋ช
๋ น ํด์ (์๋ณธ ๊ธฐ๋ฅ ์ ์ง)
|
51 |
if "1. ์ด๋ฏธ์ง ๋ณ๊ฒฝ" in prompt:
|
|
|
52 |
desc_match = re.search(r'#1์ "(.*?)"์ผ๋ก ๋ฐ๊ฟ๋ผ', prompt)
|
53 |
if desc_match:
|
54 |
description = desc_match.group(1)
|
|
|
57 |
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง๋ฅผ ์ฐฝ์์ ์ผ๋ก ๋ณํํด์ฃผ์ธ์. ๋ ์์ํ๊ณ ์์ ์ ์ธ ๋ฒ์ ์ผ๋ก ๋ง๋ค์ด์ฃผ์ธ์."
|
58 |
|
59 |
elif "2. ๊ธ์์ง์ฐ๊ธฐ" in prompt:
|
|
|
60 |
text_match = re.search(r'#1์์ "(.*?)"๋ฅผ ์ง์๋ผ', prompt)
|
61 |
if text_match:
|
62 |
text_to_remove = text_match.group(1)
|
|
|
68 |
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์ธ๋ฌผ ์ผ๊ตด์ ๋ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์ผ๊ตด๋ก ์์ฐ์ค๋ฝ๊ฒ ๊ต์ฒดํด์ฃผ์ธ์. ์ผ๊ตด์ ํ์ ๊ณผ ํน์ง์ ๋ ๋ฒ์งธ ์ด๋ฏธ์ง๋ฅผ ๋ฐ๋ฅด๋, ๋๋จธ์ง ๋ถ๋ถ์ ์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง๋ฅผ ์ ์งํด์ฃผ์ธ์."
|
69 |
|
70 |
elif "4. ์ท๋ฐ๊พธ๊ธฐ" in prompt:
|
|
|
71 |
if "#3" in prompt or "๋๋ #3" in prompt:
|
72 |
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์ธ๋ฌผ ์์์ ๋ ๋ฒ์งธ ๋๋ ์ธ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์์์ผ๋ก ์์ฐ์ค๋ฝ๊ฒ ๊ต์ฒดํด์ฃผ์ธ์. ์์์ ์คํ์ผ๊ณผ ์์์ ์ฐธ์กฐ ์ด๋ฏธ์ง๋ฅผ ๋ฐ๋ฅด๋, ์ ์ฒด ๋น์จ๊ณผ ํฌ์ฆ๋ ์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง๋ฅผ ์ ์งํด์ฃผ์ธ์."
|
73 |
else:
|
|
|
77 |
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ๋ฐฐ๊ฒฝ์ ๋ ๋ฒ์งธ ์ด๋ฏธ์ง์ ๋ฐฐ๊ฒฝ์ผ๋ก ์์ฐ์ค๋ฝ๊ฒ ๊ต์ฒดํด์ฃผ์ธ์. ์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์ฃผ์ ํผ์ฌ์ฒด๋ ์ ์งํ๊ณ , ๋ ๋ฒ์งธ ์ด๋ฏธ์ง์ ๋ฐฐ๊ฒฝ๊ณผ ์กฐํ๋กญ๊ฒ ํฉ์ฑํด์ฃผ์ธ์."
|
78 |
|
79 |
elif "6. ์ด๋ฏธ์ง ํฉ์ฑ(์ํํฌํจ)" in prompt:
|
|
|
80 |
if "#3" in prompt or "๋๋ #3" in prompt:
|
81 |
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ๋ ๋ฒ์งธ, ์ธ ๋ฒ์งธ ์ด๋ฏธ์ง๋ฅผ ์์ฐ์ค๋ฝ๊ฒ ํฉ์ฑํด์ฃผ์ธ์. ๋ชจ๋ ์ด๋ฏธ์ง์ ์ฃผ์ ์์๋ฅผ ํฌํจํ๊ณ , ํนํ ์ํ์ด ์ ๋ณด์ด๋๋ก ์กฐํ๋กญ๊ฒ ํตํฉํด์ฃผ์ธ์."
|
82 |
else:
|
|
|
85 |
elif "7. ์ด๋ฏธ์ง ํฉ์ฑ(์คํ์ผ์ ์ฉ)" in prompt:
|
86 |
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ๋ด์ฉ์ ๋ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์คํ์ผ๋ก ๋ณํํด์ฃผ์ธ์. ์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์ฃผ์ ํผ์ฌ์ฒด์ ๊ตฌ๋๋ ์ ์งํ๋, ๋ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์์ ์ ์คํ์ผ, ์์, ์ง๊ฐ์ ์ ์ฉํด์ฃผ์ธ์."
|
87 |
|
|
|
88 |
elif "์ ๋ถ์์์ผ๋ก ๋ฐ๊ฟ๋ผ" in prompt or "๋ฅผ ๋ถ์์์ผ๋ก ๋ฐ๊ฟ๋ผ" in prompt:
|
89 |
prompt = "์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง๋ฅผ ๋ถ์์ ํค์ผ๋ก ๋ณ๊ฒฝํด์ฃผ์ธ์. ์ ์ฒด์ ์ธ ์์์ ๋ถ์ ๊ณ์ด๋ก ์กฐ์ ํ๊ณ ์์ฐ์ค๋ฌ์ด ๋๋์ ์ ์งํด์ฃผ์ธ์."
|
90 |
|
|
|
91 |
prompt += " ์ด๋ฏธ์ง๋ฅผ ์์ฑํด์ฃผ์ธ์."
|
92 |
|
93 |
return prompt
|
|
|
97 |
๊ณต์ ๋ฌธ์์ ๊ธฐ๋ฐํ ์ฌ๋ฐ๋ฅธ API ํธ์ถ ๋ฐฉ์ ๊ตฌํ
|
98 |
"""
|
99 |
try:
|
|
|
100 |
api_key = os.environ.get("GEMINI_API_KEY")
|
101 |
if not api_key:
|
102 |
return None, "API ํค๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค. ํ๊ฒฝ๋ณ์๋ฅผ ํ์ธํด์ฃผ์ธ์."
|
103 |
|
|
|
104 |
client = genai.Client(api_key=api_key)
|
105 |
|
106 |
logger.info(f"Gemini API ์์ฒญ ์์ - ํ๋กฌํํธ: {prompt}")
|
107 |
|
|
|
108 |
contents = []
|
|
|
|
|
109 |
contents.append(prompt)
|
110 |
|
|
|
111 |
for idx, img in enumerate(images, 1):
|
112 |
if img is not None:
|
113 |
contents.append(img)
|
114 |
logger.info(f"์ด๋ฏธ์ง #{idx} ์ถ๊ฐ๋จ")
|
115 |
|
|
|
116 |
response = client.models.generate_content(
|
117 |
model="gemini-2.0-flash-exp-image-generation",
|
118 |
contents=contents,
|
|
|
125 |
)
|
126 |
)
|
127 |
|
|
|
128 |
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp:
|
129 |
temp_path = tmp.name
|
130 |
|
131 |
result_text = ""
|
132 |
image_found = False
|
133 |
|
|
|
134 |
for part in response.candidates[0].content.parts:
|
135 |
if hasattr(part, 'text') and part.text:
|
136 |
result_text += part.text
|
|
|
143 |
if not image_found:
|
144 |
return None, f"API์์ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ์ง ๋ชปํ์ต๋๋ค. ์๋ต ํ
์คํธ: {result_text}"
|
145 |
|
|
|
146 |
result_img = Image.open(temp_path)
|
147 |
if result_img.mode == "RGBA":
|
148 |
result_img = result_img.convert("RGB")
|
|
|
158 |
3๊ฐ์ ์ด๋ฏธ์ง์ ํ๋กฌํํธ๋ฅผ ์ฒ๋ฆฌํ๋ ํจ์
|
159 |
"""
|
160 |
try:
|
|
|
161 |
images = [image1, image2, image3]
|
162 |
valid_images = [img for img in images if img is not None]
|
163 |
|
164 |
if not valid_images:
|
165 |
return None, "์ ์ด๋ ํ๋์ ์ด๋ฏธ์ง๋ฅผ ์
๋ก๋ํด์ฃผ์ธ์."
|
166 |
|
|
|
167 |
if not prompt or not prompt.strip():
|
|
|
168 |
if len(valid_images) == 1:
|
169 |
prompt = "Please creatively transform this image into a more vivid and artistic version."
|
170 |
logger.info("Default prompt generated for single image")
|
|
|
175 |
prompt = "Please creatively composite these three images, combining their main elements into a cohesive and natural scene."
|
176 |
logger.info("Default prompt generated for three images")
|
177 |
else:
|
|
|
178 |
prompt = preprocess_prompt(prompt, image1, image2, image3)
|
179 |
|
|
|
180 |
return generate_with_images(prompt, valid_images)
|
181 |
|
182 |
except Exception as e:
|
183 |
logger.exception("์ด๋ฏธ์ง ์ฒ๋ฆฌ ์ค ์ค๋ฅ ๋ฐ์:")
|
184 |
return None, f"์ค๋ฅ ๋ฐ์: {str(e)}"
|
185 |
|
186 |
+
def process_and_show_prompt(image1, image2, image3, prompt):
|
187 |
+
images = [image1, image2, image3]
|
188 |
+
valid_images = [img for img in images if img is not None]
|
189 |
+
|
190 |
+
try:
|
191 |
+
auto_prompt = prompt
|
192 |
+
if not prompt or not prompt.strip():
|
193 |
+
if len(valid_images) == 1:
|
194 |
+
auto_prompt = "Please creatively transform this image into a more vivid and artistic version."
|
195 |
+
elif len(valid_images) == 2:
|
196 |
+
auto_prompt = "Please seamlessly composite these two images, integrating their key elements harmoniously into a single image."
|
197 |
+
else:
|
198 |
+
auto_prompt = "Please creatively composite these three images, combining their main elements into a cohesive and natural scene."
|
199 |
+
else:
|
200 |
+
auto_prompt = preprocess_prompt(prompt, image1, image2, image3)
|
201 |
+
|
202 |
+
result_img, status = process_images_with_prompt(image1, image2, image3, prompt)
|
203 |
+
|
204 |
+
return result_img, status, auto_prompt
|
205 |
+
except Exception as e:
|
206 |
+
logger.exception("์ฒ๋ฆฌ ์ค ์ค๋ฅ ๋ฐ์:")
|
207 |
+
return None, f"์ค๋ฅ ๋ฐ์: {str(e)}", prompt
|
208 |
|
209 |
# Gradio ์ธํฐํ์ด์ค
|
210 |
with gr.Blocks() as demo:
|
|
|
232 |
label="ํ๋กฌํํธ (์ ํ ์ฌํญ)"
|
233 |
)
|
234 |
|
235 |
+
# ์ ํ ์ต์
(๋งํฌ๋ค์ด์ผ๋ก ์๋ด)
|
236 |
+
with gr.Row():
|
237 |
+
gr.Markdown(
|
238 |
+
"**์ ํ ์ต์
:**\n\n"
|
239 |
+
"- **์ด๋ฏธ์ง ๋ณ๊ฒฝ**: `Change image #1 to [another look]`\n"
|
240 |
+
"- **๊ธ์์ง์ฐ๊ธฐ**: `#1 Remove [all Chinese] from the image.`"
|
241 |
+
)
|
242 |
+
with gr.Row():
|
243 |
+
image_change_btn = gr.Button("์ด๋ฏธ์ง ๋ณ๊ฒฝ")
|
244 |
+
text_remove_btn = gr.Button("๊ธ์์ง์ฐ๊ธฐ")
|
245 |
+
|
246 |
# ์์ฑ ๋ฒํผ
|
247 |
submit_btn = gr.Button("์ด๋ฏธ์ง ์์ฑ", variant="primary")
|
248 |
|
249 |
with gr.Column():
|
|
|
250 |
output_image = gr.Image(label="์์ฑ๋ ์ด๋ฏธ์ง")
|
251 |
output_text = gr.Textbox(label="์ํ ๋ฉ์์ง")
|
|
|
|
|
252 |
prompt_display = gr.Textbox(label="์ฌ์ฉ๋ ํ๋กฌํํธ", visible=True)
|
253 |
|
254 |
+
# ์ ํ ์ต์
๋ฒํผ ํด๋ฆญ ์ ํ๋กฌํํธ ์
๋ ฅ๋ ์
๋ฐ์ดํธ
|
255 |
+
image_change_btn.click(
|
256 |
+
fn=lambda: "Change image #1 to [another look]",
|
257 |
+
inputs=[],
|
258 |
+
outputs=prompt_input
|
259 |
+
)
|
260 |
+
text_remove_btn.click(
|
261 |
+
fn=lambda: "#1 Remove [all Chinese] from the image.",
|
262 |
+
inputs=[],
|
263 |
+
outputs=prompt_input
|
264 |
+
)
|
265 |
+
|
266 |
# ์ด๋ฏธ์ง ์์ฑ ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
267 |
submit_btn.click(
|
268 |
fn=process_and_show_prompt,
|
269 |
inputs=[image1_input, image2_input, image3_input, prompt_input],
|
|
|
277 |
1. **์๋ ํฉ์ฑ**: ์ด๋ฏธ์ง๋ง ์
๋ก๋ํ๊ณ ํ๋กฌํํธ๋ฅผ ๋น์๋๋ฉด ์๋์ผ๋ก ํฉ์ฑ๋ฉ๋๋ค.
|
278 |
2. **์ด๋ฏธ์ง ์ฐธ์กฐ**: #1, #2, #3์ผ๋ก ๊ฐ ์ด๋ฏธ์ง๋ฅผ ์ฐธ์กฐํ ์ ์์ต๋๋ค.
|
279 |
3. **์ผ๋ถ ์ด๋ฏธ์ง๋ง**: ํ์ํ ์ด๋ฏธ์ง๋ง ์
๋ก๋ํด๋ ๊ธฐ๋ฅ ์คํ์ด ๊ฐ๋ฅํฉ๋๋ค.
|
280 |
+
4. **์ ํ ์ต์
**: ์์ ์ ํ ์ต์
์์ ์ํ๋ ํญ๋ชฉ์ ํด๋ฆญํ๋ฉด ํ๋กฌํํธ ์
๋ ฅ๋์ ๋ฐ๋ก ์ ์ฉ๋ฉ๋๋ค.
|
281 |
|
282 |
> **ํ**: ํ๋กฌํํธ๋ฅผ ์ง์ ์์ ํ ์๋ ์์ต๋๋ค.
|
283 |
"""
|
284 |
)
|
285 |
|
|
|
286 |
if __name__ == "__main__":
|
287 |
demo.launch(share=True)
|