ssboost commited on
Commit
a0c634e
Β·
verified Β·
1 Parent(s): 40783d1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +81 -29
app.py CHANGED
@@ -81,9 +81,44 @@ def enhance_image_quality(image):
81
 
82
  return image
83
 
84
- def rotate_image_slightly(image, angle=5):
85
- """이미지λ₯Ό μ•½κ°„ νšŒμ „μ‹œμΌœ μ•„μ΄ν…œ μœ„λ„ˆ νšŒν”Ό"""
86
- return image.rotate(angle, expand=True, fillcolor=(255, 255, 255))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
  def check_white_background_ratio(image, threshold=0.85):
89
  """흰색 λ°°κ²½ λΉ„μœ¨ 확인 (85% κ·œμΉ™)"""
@@ -134,7 +169,7 @@ def process_with_ai_enhancement(image_path, prompt_option):
134
  except Exception as e:
135
  return None, f"AI 처리 쀑 였λ₯˜: {str(e)}"
136
 
137
- def create_coupang_thumbnail(image, apply_shadow, apply_rotation, rotation_angle, ai_enhancement, prompt_option):
138
  """쿠팑 썸넀일 생성 메인 ν•¨μˆ˜"""
139
  if image is None:
140
  return None, "이미지λ₯Ό μ—…λ‘œλ“œν•΄μ£Όμ„Έμš”."
@@ -143,7 +178,21 @@ def create_coupang_thumbnail(image, apply_shadow, apply_rotation, rotation_angle
143
  result_image = image.copy()
144
  status_messages = []
145
 
146
- # 1단계: AI ν–₯상 (선택사항)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  if ai_enhancement and REPLICATE_API_TOKEN:
148
  temp_path = upload_image_to_temp_url(result_image)
149
  if temp_path:
@@ -155,15 +204,10 @@ def create_coupang_thumbnail(image, apply_shadow, apply_rotation, rotation_angle
155
  status_messages.append(f"❌ AI ν–₯상: {ai_msg}")
156
  os.unlink(temp_path) # μž„μ‹œ 파일 μ‚­μ œ
157
 
158
- # 2단계: ν™”μ§ˆ ν–₯상
159
  result_image = enhance_image_quality(result_image)
160
  status_messages.append("βœ… ν™”μ§ˆ ν–₯상 μ™„λ£Œ")
161
 
162
- # 3단계: 각도 λ³€κ²½ (μ•„μ΄ν…œ μœ„λ„ˆ νšŒν”Ό)
163
- if apply_rotation:
164
- result_image = rotate_image_slightly(result_image, rotation_angle)
165
- status_messages.append(f"βœ… 각도 λ³€κ²½: {rotation_angle}도 νšŒμ „")
166
-
167
  # 4단계: 흰 λ°°κ²½ + 그림자 효과
168
  if apply_shadow:
169
  result_image = create_white_background_shadow(result_image)
@@ -202,7 +246,7 @@ def create_interface():
202
  ## πŸ’‘ μ μš©λ˜λŠ” 쿠팑 κ·œμ • λŒ€μ‘ μ „λž΅:
203
  - βœ… **흰 λ°°κ²½ + 85% κ·œμΉ™** μ™„λ²½ μ€€μˆ˜
204
  - βœ… **AI λ§ˆλ²• ν”„λ‘¬ν”„νŠΈ**둜 ν™”μ§ˆ ν–₯상
205
- - βœ… **각도 λ³€κ²½**으둜 μ•„μ΄ν…œ μœ„λ„ˆ νšŒν”Ό
206
  - βœ… **그림자 효과**둜 μžμ—°μŠ€λŸ¬μš΄ μž…μ²΄κ° μ—°μΆœ
207
  """)
208
 
@@ -224,17 +268,16 @@ def create_interface():
224
  value=True,
225
  info="μžμ—°μŠ€λŸ¬μš΄ μž…μ²΄κ° μ—°μΆœ"
226
  )
227
- apply_rotation = gr.Checkbox(
228
- label="각도 λ³€κ²½ 적용",
229
  value=True,
230
- info="μ•„μ΄ν…œ μœ„λ„ˆ νšŒν”Ό"
231
  )
232
- rotation_angle = gr.Slider(
233
- minimum=-15,
234
- maximum=15,
235
- value=5,
236
- step=1,
237
- label="νšŒμ „ 각도",
238
  visible=True
239
  )
240
 
@@ -270,9 +313,18 @@ def create_interface():
270
  ---
271
  ## πŸ“‹ μ‚¬μš© 방법
272
  1. **배경이 제거된 μƒν’ˆ 이미지**λ₯Ό μ—…λ‘œλ“œν•˜μ„Έμš”
273
- 2. μ›ν•˜λŠ” **효과 μ˜΅μ…˜**을 μ„ νƒν•˜μ„Έμš”
274
- 3. **AI ν–₯상**을 μ‚¬μš©ν•˜λ €λ©΄ Replicate API 토큰을 ν™˜κ²½λ³€μˆ˜λ‘œ μ„€μ •ν•˜μ„Έμš”
275
- 4. **'쿠팑 썸넀일 생성'** λ²„νŠΌμ„ ν΄λ¦­ν•˜μ„Έμš”
 
 
 
 
 
 
 
 
 
276
 
277
  ## πŸ”‘ API μ„€μ • (선택사항)
278
  AI ν–₯상 κΈ°λŠ₯을 μ‚¬μš©ν•˜λ €λ©΄ ν™˜κ²½λ³€μˆ˜λ₯Ό μ„€μ •ν•˜μ„Έμš”:
@@ -282,18 +334,18 @@ def create_interface():
282
  """)
283
 
284
  # 이벀트 처리
285
- def update_rotation_visibility(apply_rot):
286
- return gr.update(visible=apply_rot)
287
 
288
- apply_rotation.change(update_rotation_visibility, apply_rotation, rotation_angle)
289
 
290
  process_btn.click(
291
  create_coupang_thumbnail,
292
  inputs=[
293
  input_image,
294
  apply_shadow,
295
- apply_rotation,
296
- rotation_angle,
297
  ai_enhancement,
298
  prompt_option
299
  ],
 
81
 
82
  return image
83
 
84
+ def change_product_angle_with_ai(image_path, angle_option):
85
+ """AIλ₯Ό μ΄μš©ν•œ μƒν’ˆ 각도/λ°©ν–₯ λ³€κ²½μœΌλ‘œ μ•„μ΄ν…œ μœ„λ„ˆ νšŒν”Ό"""
86
+ if not REPLICATE_API_TOKEN:
87
+ return None, "Replicate API 토큰이 μ„€μ •λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€."
88
+
89
+ try:
90
+ # 각도 λ³€κ²½ ν”„λ‘¬ν”„νŠΈ μ˜΅μ…˜
91
+ angle_prompts = {
92
+ "μ™Όμͺ½ 45도": "Change the product angle to show it from 45-degree left side view, professional product photography, white background",
93
+ "였λ₯Έμͺ½ 45도": "Change the product angle to show it from 45-degree right side view, professional product photography, white background",
94
+ "상단 μ•΅κΈ€": "Change to top-down angle view of the product, bird's eye view, professional product photography, white background",
95
+ "3/4 λ·°": "Change to 3/4 angle view of the product, three-quarter perspective, professional product photography, white background",
96
+ "μ •λ©΄μ—μ„œ μΈ‘λ©΄": "Change from front view to side view of the product, profile angle, professional product photography, white background",
97
+ "μΈ‘λ©΄μ—μ„œ μ •λ©΄": "Change from side view to front view of the product, frontal angle, professional product photography, white background"
98
+ }
99
+
100
+ selected_prompt = angle_prompts.get(angle_option, angle_prompts["3/4 λ·°"])
101
+
102
+ # Replicate API 호좜
103
+ output = replicate.run(
104
+ "black-forest-labs/flux-kontext-pro",
105
+ input={
106
+ "prompt": selected_prompt,
107
+ "input_image": open(image_path, "rb"),
108
+ "output_format": "jpg"
109
+ }
110
+ )
111
+
112
+ # κ²°κ³Ό 이미지 λ‹€μš΄λ‘œλ“œ
113
+ response = requests.get(output)
114
+ if response.status_code == 200:
115
+ angled_image = Image.open(io.BytesIO(response.content))
116
+ return angled_image, f"μƒν’ˆ 각도 λ³€κ²½ μ™„λ£Œ: {angle_option}"
117
+ else:
118
+ return None, "각도 λ³€κ²½ μ‹€νŒ¨"
119
+
120
+ except Exception as e:
121
+ return None, f"각도 λ³€κ²½ 쀑 였λ₯˜: {str(e)}"
122
 
123
  def check_white_background_ratio(image, threshold=0.85):
124
  """흰색 λ°°κ²½ λΉ„μœ¨ 확인 (85% κ·œμΉ™)"""
 
169
  except Exception as e:
170
  return None, f"AI 처리 쀑 였λ₯˜: {str(e)}"
171
 
172
+ def create_coupang_thumbnail(image, apply_shadow, apply_angle_change, angle_option, ai_enhancement, prompt_option):
173
  """쿠팑 썸넀일 생성 메인 ν•¨μˆ˜"""
174
  if image is None:
175
  return None, "이미지λ₯Ό μ—…λ‘œλ“œν•΄μ£Όμ„Έμš”."
 
178
  result_image = image.copy()
179
  status_messages = []
180
 
181
+ # 1단계: μƒν’ˆ 각도 λ³€κ²½ (μ•„μ΄ν…œ μœ„λ„ˆ νšŒν”Ό)
182
+ if apply_angle_change and REPLICATE_API_TOKEN:
183
+ temp_path = upload_image_to_temp_url(result_image)
184
+ if temp_path:
185
+ angled_img, angle_msg = change_product_angle_with_ai(temp_path, angle_option)
186
+ if angled_img:
187
+ result_image = angled_img
188
+ status_messages.append(f"βœ… μƒν’ˆ 각도 λ³€κ²½: {angle_msg}")
189
+ else:
190
+ status_messages.append(f"❌ 각도 λ³€κ²½: {angle_msg}")
191
+ os.unlink(temp_path) # μž„μ‹œ 파일 μ‚­μ œ
192
+ elif apply_angle_change and not REPLICATE_API_TOKEN:
193
+ status_messages.append("⚠️ 각도 λ³€κ²½μ—λŠ” Replicate API 토큰이 ν•„μš”ν•©λ‹ˆλ‹€")
194
+
195
+ # 2단계: AI ν’ˆμ§ˆ ν–₯상 (선택사항)
196
  if ai_enhancement and REPLICATE_API_TOKEN:
197
  temp_path = upload_image_to_temp_url(result_image)
198
  if temp_path:
 
204
  status_messages.append(f"❌ AI ν–₯상: {ai_msg}")
205
  os.unlink(temp_path) # μž„μ‹œ 파일 μ‚­μ œ
206
 
207
+ # 3단계: ν™”μ§ˆ ν–₯상
208
  result_image = enhance_image_quality(result_image)
209
  status_messages.append("βœ… ν™”μ§ˆ ν–₯상 μ™„λ£Œ")
210
 
 
 
 
 
 
211
  # 4단계: 흰 λ°°κ²½ + 그림자 효과
212
  if apply_shadow:
213
  result_image = create_white_background_shadow(result_image)
 
246
  ## πŸ’‘ μ μš©λ˜λŠ” 쿠팑 κ·œμ • λŒ€μ‘ μ „λž΅:
247
  - βœ… **흰 λ°°κ²½ + 85% κ·œμΉ™** μ™„λ²½ μ€€μˆ˜
248
  - βœ… **AI λ§ˆλ²• ν”„λ‘¬ν”„νŠΈ**둜 ν™”μ§ˆ ν–₯상
249
+ - βœ… **μƒν’ˆ 각도 λ³€κ²½**으둜 μ•„μ΄ν…œ μœ„λ„ˆ(쀑볡) νšŒν”Ό
250
  - βœ… **그림자 효과**둜 μžμ—°μŠ€λŸ¬μš΄ μž…μ²΄κ° μ—°μΆœ
251
  """)
252
 
 
268
  value=True,
269
  info="μžμ—°μŠ€λŸ¬μš΄ μž…μ²΄κ° μ—°μΆœ"
270
  )
271
+ apply_angle_change = gr.Checkbox(
272
+ label="μƒν’ˆ 각도 λ³€κ²½ (μ•„μ΄ν…œ μœ„λ„ˆ νšŒν”Ό)",
273
  value=True,
274
+ info="AI둜 μƒν’ˆμ˜ 각도/λ°©ν–₯을 λ³€κ²½ν•˜μ—¬ 쀑볡 νšŒν”Ό"
275
  )
276
+ angle_option = gr.Dropdown(
277
+ choices=["μ™Όμͺ½ 45도", "였λ₯Έμͺ½ 45도", "상단 μ•΅κΈ€", "3/4 λ·°", "μ •λ©΄μ—μ„œ μΈ‘λ©΄", "μΈ‘λ©΄μ—μ„œ μ •λ©΄"],
278
+ value="3/4 λ·°",
279
+ label="λ³€κ²½ν•  각도",
280
+ info="μƒν’ˆμ„ μ–΄λ–€ κ°λ„λ‘œ λ³€κ²½ν• μ§€ 선택",
 
281
  visible=True
282
  )
283
 
 
313
  ---
314
  ## πŸ“‹ μ‚¬μš© 방법
315
  1. **배경이 제거된 μƒν’ˆ 이미지**λ₯Ό μ—…λ‘œλ“œν•˜μ„Έμš”
316
+ 2. **μƒν’ˆ 각도 λ³€κ²½ μ˜΅μ…˜**을 μ„ νƒν•˜μ—¬ μ•„μ΄ν…œ μœ„λ„ˆ(쀑볡)λ₯Ό νšŒν”Όν•˜μ„Έμš”
317
+ 3. μ›ν•˜λŠ” **효과 μ˜΅μ…˜**을 μ„ νƒν•˜μ„Έμš”
318
+ 4. **AI ν–₯상**을 μ‚¬μš©ν•˜λ €λ©΄ Replicate API 토큰을 ν™˜κ²½λ³€μˆ˜λ‘œ μ„€μ •ν•˜μ„Έμš”
319
+ 5. **'쿠팑 썸넀일 생성'** λ²„νŠΌμ„ ν΄λ¦­ν•˜μ„Έμš”
320
+
321
+ ## 🎯 μƒν’ˆ 각도 λ³€κ²½ μ˜΅μ…˜ μ„€λͺ…
322
+ - **μ™Όμͺ½ 45도**: μƒν’ˆμ„ μ™Όμͺ½μ—μ„œ 45도 κ°λ„λ‘œ μ΄¬μ˜ν•œ λŠλ‚Œ
323
+ - **였λ₯Έμͺ½ 45도**: μƒν’ˆμ„ 였λ₯Έμͺ½μ—μ„œ 45도 κ°λ„λ‘œ μ΄¬μ˜ν•œ λŠλ‚Œ
324
+ - **상단 μ•΅κΈ€**: μœ„μ—μ„œ λ‚΄λ €λ‹€λ³Έ 탑뷰 각도
325
+ - **3/4 λ·°**: κ°€μž₯ 일반적인 μƒν’ˆ 촬영 각도 (μΆ”μ²œ)
326
+ - **μ •λ©΄μ—μ„œ μΈ‘λ©΄**: μ •λ©΄ 이미지λ₯Ό μΈ‘λ©΄ κ°λ„λ‘œ λ³€κ²½
327
+ - **μΈ‘λ©΄μ—μ„œ μ •λ©΄**: μΈ‘λ©΄ 이미지λ₯Ό μ •λ©΄ κ°λ„λ‘œ λ³€κ²½
328
 
329
  ## πŸ”‘ API μ„€μ • (선택사항)
330
  AI ν–₯상 κΈ°λŠ₯을 μ‚¬μš©ν•˜λ €λ©΄ ν™˜κ²½λ³€μˆ˜λ₯Ό μ„€μ •ν•˜μ„Έμš”:
 
334
  """)
335
 
336
  # 이벀트 처리
337
+ def update_angle_visibility(apply_angle):
338
+ return gr.update(visible=apply_angle)
339
 
340
+ apply_angle_change.change(update_angle_visibility, apply_angle_change, angle_option)
341
 
342
  process_btn.click(
343
  create_coupang_thumbnail,
344
  inputs=[
345
  input_image,
346
  apply_shadow,
347
+ apply_angle_change,
348
+ angle_option,
349
  ai_enhancement,
350
  prompt_option
351
  ],