Update app.py
Browse files
app.py
CHANGED
|
@@ -62,44 +62,46 @@ def upscale_with_clarity(image_path):
|
|
| 62 |
except Exception as e:
|
| 63 |
return None, f"ํ์ง ๊ฐ์ ์ค๋ฅ: {str(e)}"
|
| 64 |
|
| 65 |
-
def
|
| 66 |
-
"""
|
|
|
|
|
|
|
|
|
|
| 67 |
try:
|
| 68 |
-
#
|
| 69 |
-
|
| 70 |
-
image = image.convert('RGB')
|
| 71 |
-
|
| 72 |
-
# ์ด๋ฏธ์ง๋ฅผ numpy ๋ฐฐ์ด๋ก ๋ณํ
|
| 73 |
-
img_array = np.array(image)
|
| 74 |
-
|
| 75 |
-
# ๋ฐฐ๊ฒฝ์ผ๋ก ํ๋จ๋๋ ์์ญ ์ฐพ๊ธฐ (๋ฐ์ ์์ ์์ญ)
|
| 76 |
-
# ๊ฐ ํฝ์
์ RGB ๊ฐ์ด ๋ชจ๋ threshold ์ด์์ธ ๊ฒฝ์ฐ ๋ฐฐ๊ฒฝ์ผ๋ก ํ๋จ
|
| 77 |
-
background_mask = np.all(img_array >= threshold, axis=-1)
|
| 78 |
-
|
| 79 |
-
# ๋ฐฐ๊ฒฝ ์์ญ์ ์์ ํ ํฐ์(255, 255, 255)์ผ๋ก ๋ณ๊ฒฝ
|
| 80 |
-
img_array[background_mask] = [255, 255, 255]
|
| 81 |
-
|
| 82 |
-
# numpy ๋ฐฐ์ด์ ๋ค์ PIL ์ด๋ฏธ์ง๋ก ๋ณํ
|
| 83 |
-
result_image = Image.fromarray(img_array)
|
| 84 |
|
| 85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
except Exception as e:
|
| 88 |
-
return
|
| 89 |
|
| 90 |
-
def
|
| 91 |
-
"""
|
| 92 |
if not REPLICATE_API_TOKEN:
|
| 93 |
return None, "Replicate API ํ ํฐ์ด ํ์ํฉ๋๋ค."
|
| 94 |
|
| 95 |
try:
|
| 96 |
-
#
|
| 97 |
-
|
| 98 |
|
| 99 |
output = replicate.run(
|
| 100 |
"black-forest-labs/flux-kontext-pro",
|
| 101 |
input={
|
| 102 |
-
"prompt":
|
| 103 |
"input_image": open(image_path, "rb"),
|
| 104 |
"output_format": "jpg"
|
| 105 |
}
|
|
@@ -107,17 +109,12 @@ def create_coupang_thumbnail_fixed(image_path):
|
|
| 107 |
|
| 108 |
response = requests.get(output)
|
| 109 |
if response.status_code == 200:
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
# ์์ฑ๋ ์ด๋ฏธ์ง์ ๋ฐฐ๊ฒฝ์ ๊ฐ์ ๋ก ์์ ํ ํฐ์์ผ๋ก ๋ณ๊ฒฝ
|
| 113 |
-
final_image, white_bg_msg = force_white_background(generated_image)
|
| 114 |
-
|
| 115 |
-
return final_image, f"์ธ๋ค์ผ ์์ฑ ์๋ฃ + {white_bg_msg}"
|
| 116 |
else:
|
| 117 |
-
return None, "
|
| 118 |
|
| 119 |
except Exception as e:
|
| 120 |
-
return None, f"
|
| 121 |
|
| 122 |
def process_image(image, remove_bg, upscale_quality):
|
| 123 |
"""๋ฉ์ธ ์ฒ๋ฆฌ ํจ์"""
|
|
@@ -128,7 +125,18 @@ def process_image(image, remove_bg, upscale_quality):
|
|
| 128 |
result_image = image.copy()
|
| 129 |
status_messages = []
|
| 130 |
|
| 131 |
-
# 1๋จ๊ณ:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
if remove_bg:
|
| 133 |
temp_path = upload_image_to_temp_url(result_image)
|
| 134 |
if temp_path:
|
|
@@ -140,19 +148,18 @@ def process_image(image, remove_bg, upscale_quality):
|
|
| 140 |
status_messages.append(f"โ {bg_msg}")
|
| 141 |
os.unlink(temp_path)
|
| 142 |
|
| 143 |
-
#
|
| 144 |
temp_path = upload_image_to_temp_url(result_image)
|
| 145 |
if temp_path:
|
| 146 |
-
|
| 147 |
-
if
|
| 148 |
-
result_image =
|
| 149 |
-
status_messages.append(f"โ
{
|
| 150 |
else:
|
| 151 |
-
status_messages.append(f"โ {
|
| 152 |
-
return None, "\n".join(status_messages)
|
| 153 |
os.unlink(temp_path)
|
| 154 |
|
| 155 |
-
#
|
| 156 |
if upscale_quality:
|
| 157 |
temp_path = upload_image_to_temp_url(result_image)
|
| 158 |
if temp_path:
|
|
@@ -164,7 +171,7 @@ def process_image(image, remove_bg, upscale_quality):
|
|
| 164 |
status_messages.append(f"โ {upscale_msg}")
|
| 165 |
os.unlink(temp_path)
|
| 166 |
|
| 167 |
-
#
|
| 168 |
result_image = result_image.resize((1000, 1000), Image.Resampling.LANCZOS)
|
| 169 |
status_messages.append("โ
1000x1000 ํฌ๊ธฐ ์กฐ์ ์๋ฃ")
|
| 170 |
|
|
|
|
| 62 |
except Exception as e:
|
| 63 |
return None, f"ํ์ง ๊ฐ์ ์ค๋ฅ: {str(e)}"
|
| 64 |
|
| 65 |
+
def change_product_angle(image_path):
|
| 66 |
+
"""์ํ ๊ฐ๋๋ฅผ ํ์ด์ ๋ณ๊ฒฝ"""
|
| 67 |
+
if not REPLICATE_API_TOKEN:
|
| 68 |
+
return None, "Replicate API ํ ํฐ์ด ํ์ํฉ๋๋ค."
|
| 69 |
+
|
| 70 |
try:
|
| 71 |
+
# ๊ฐ๋ ๋ณ๊ฒฝ ํ๋กฌํํธ (๋ฐฐ๊ฒฝ์ ์ ๊ฒฝ์ฐ์ง ์๊ณ ๊ฐ๋๋ง ์ง์ค)
|
| 72 |
+
angle_prompt = "Change product angle to dramatic 3/4 view rotated 45 degrees, dynamic perspective, tilted composition, angled product placement, professional product photography"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
|
| 74 |
+
output = replicate.run(
|
| 75 |
+
"black-forest-labs/flux-kontext-pro",
|
| 76 |
+
input={
|
| 77 |
+
"prompt": angle_prompt,
|
| 78 |
+
"input_image": open(image_path, "rb"),
|
| 79 |
+
"output_format": "jpg"
|
| 80 |
+
}
|
| 81 |
+
)
|
| 82 |
|
| 83 |
+
response = requests.get(output)
|
| 84 |
+
if response.status_code == 200:
|
| 85 |
+
return Image.open(io.BytesIO(response.content)), "๊ฐ๋ ๋ณ๊ฒฝ ์๋ฃ"
|
| 86 |
+
else:
|
| 87 |
+
return None, "๊ฐ๋ ๋ณ๊ฒฝ ์คํจ"
|
| 88 |
+
|
| 89 |
except Exception as e:
|
| 90 |
+
return None, f"๊ฐ๋ ๋ณ๊ฒฝ ์ค๋ฅ: {str(e)}"
|
| 91 |
|
| 92 |
+
def add_shadow_only(image_path):
|
| 93 |
+
"""๋ฐฐ๊ฒฝ ์ ๊ฑฐ๋ ์ํ์ ๊ทธ๋ฆผ์๋ง ์ถ๊ฐ (์์ ํ ํฐ์ ๋ฐฐ๊ฒฝ)"""
|
| 94 |
if not REPLICATE_API_TOKEN:
|
| 95 |
return None, "Replicate API ํ ํฐ์ด ํ์ํฉ๋๋ค."
|
| 96 |
|
| 97 |
try:
|
| 98 |
+
# ๊ทธ๋ฆผ์ ์ถ๊ฐ ํ๋กฌํํธ (์์ ํ ํฐ์ ๋ฐฐ๊ฒฝ + ๊ทธ๋ฆผ์ ํจ๊ณผ๋ง)
|
| 99 |
+
shadow_prompt = "Add natural soft drop shadow to the product on pure white background #FFFFFF, clean white backdrop, subtle shadow on white surface, professional e-commerce photo, solid white background, product takes 85% of image space"
|
| 100 |
|
| 101 |
output = replicate.run(
|
| 102 |
"black-forest-labs/flux-kontext-pro",
|
| 103 |
input={
|
| 104 |
+
"prompt": shadow_prompt,
|
| 105 |
"input_image": open(image_path, "rb"),
|
| 106 |
"output_format": "jpg"
|
| 107 |
}
|
|
|
|
| 109 |
|
| 110 |
response = requests.get(output)
|
| 111 |
if response.status_code == 200:
|
| 112 |
+
return Image.open(io.BytesIO(response.content)), "๊ทธ๋ฆผ์ ์ถ๊ฐ ์๋ฃ"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
else:
|
| 114 |
+
return None, "๊ทธ๋ฆผ์ ์ถ๊ฐ ์คํจ"
|
| 115 |
|
| 116 |
except Exception as e:
|
| 117 |
+
return None, f"๊ทธ๋ฆผ์ ์ถ๊ฐ ์ค๋ฅ: {str(e)}"
|
| 118 |
|
| 119 |
def process_image(image, remove_bg, upscale_quality):
|
| 120 |
"""๋ฉ์ธ ์ฒ๋ฆฌ ํจ์"""
|
|
|
|
| 125 |
result_image = image.copy()
|
| 126 |
status_messages = []
|
| 127 |
|
| 128 |
+
# 1๋จ๊ณ: ์ํ ๊ฐ๋ ๋ณ๊ฒฝ
|
| 129 |
+
temp_path = upload_image_to_temp_url(result_image)
|
| 130 |
+
if temp_path:
|
| 131 |
+
angled_img, angle_msg = change_product_angle(temp_path)
|
| 132 |
+
if angled_img:
|
| 133 |
+
result_image = angled_img
|
| 134 |
+
status_messages.append(f"โ
{angle_msg}")
|
| 135 |
+
else:
|
| 136 |
+
status_messages.append(f"โ {angle_msg}")
|
| 137 |
+
os.unlink(temp_path)
|
| 138 |
+
|
| 139 |
+
# 2๋จ๊ณ: ๋ฐฐ๊ฒฝ ์ ๊ฑฐ (๋๋ผ)
|
| 140 |
if remove_bg:
|
| 141 |
temp_path = upload_image_to_temp_url(result_image)
|
| 142 |
if temp_path:
|
|
|
|
| 148 |
status_messages.append(f"โ {bg_msg}")
|
| 149 |
os.unlink(temp_path)
|
| 150 |
|
| 151 |
+
# 3๋จ๊ณ: ๊ทธ๋ฆผ์๋ง ์ถ๊ฐ (์์ ํ ํฐ์ ๋ฐฐ๊ฒฝ)
|
| 152 |
temp_path = upload_image_to_temp_url(result_image)
|
| 153 |
if temp_path:
|
| 154 |
+
shadow_img, shadow_msg = add_shadow_only(temp_path)
|
| 155 |
+
if shadow_img:
|
| 156 |
+
result_image = shadow_img
|
| 157 |
+
status_messages.append(f"โ
{shadow_msg}")
|
| 158 |
else:
|
| 159 |
+
status_messages.append(f"โ {shadow_msg}")
|
|
|
|
| 160 |
os.unlink(temp_path)
|
| 161 |
|
| 162 |
+
# 4๋จ๊ณ: ํ์ง ๊ฐ์ (์ด๋ฏธ์ง ์์ฑ ํ)
|
| 163 |
if upscale_quality:
|
| 164 |
temp_path = upload_image_to_temp_url(result_image)
|
| 165 |
if temp_path:
|
|
|
|
| 171 |
status_messages.append(f"โ {upscale_msg}")
|
| 172 |
os.unlink(temp_path)
|
| 173 |
|
| 174 |
+
# 5๋จ๊ณ: ์ต์ข
ํฌ๊ธฐ ์กฐ์
|
| 175 |
result_image = result_image.resize((1000, 1000), Image.Resampling.LANCZOS)
|
| 176 |
status_messages.append("โ
1000x1000 ํฌ๊ธฐ ์กฐ์ ์๋ฃ")
|
| 177 |
|