Download app.py from ssboost/df3esdf: direct link, hf CLI and curl.
- Browser
- Download file 9.11 kB
-
https://huggingface.co/spaces/ssboost/df3esdf/resolve/main/app.py
- Command line
-
hf download hf://spaces/ssboost/df3esdf/app.py
-
curl -L -o app.py https://huggingface.co/spaces/ssboost/df3esdf/resolve/main/app.py
9.11 kB
| import gradio as gr | |
| import replicate | |
| import os | |
| import requests | |
| from PIL import Image, ImageDraw, ImageFilter, ImageEnhance | |
| import io | |
| import tempfile | |
| import numpy as np | |
| # Replicate API ํ ํฐ ์ค์ | |
| REPLICATE_API_TOKEN = os.getenv("REPLICATE_API_TOKEN") | |
| if REPLICATE_API_TOKEN: | |
| os.environ["REPLICATE_API_TOKEN"] = REPLICATE_API_TOKEN | |
| def upload_image_to_temp_url(image): | |
| """์ด๋ฏธ์ง๋ฅผ ์์ ํ์ผ๋ก ์ ์ฅ""" | |
| if image is None: | |
| return None | |
| with tempfile.NamedTemporaryFile(delete=False, suffix='.png') as tmp_file: | |
| image.save(tmp_file.name, format='PNG') | |
| return tmp_file.name | |
| def remove_background_with_ai(image_path): | |
| """AI ๋ฐฐ๊ฒฝ ์ ๊ฑฐ""" | |
| if not REPLICATE_API_TOKEN: | |
| return None, "Replicate API ํ ํฐ์ด ํ์ํฉ๋๋ค." | |
| try: | |
| output = replicate.run( | |
| "851-labs/background-remover:a029dff38972b5fda4ec5d75d7d1cd25aeff621d2cf4946a41055d7db66b80bc", | |
| input={"image": open(image_path, "rb")} | |
| ) | |
| response = requests.get(output) | |
| if response.status_code == 200: | |
| return Image.open(io.BytesIO(response.content)), "๋ฐฐ๊ฒฝ ์ ๊ฑฐ ์๋ฃ" | |
| else: | |
| return None, "๋ฐฐ๊ฒฝ ์ ๊ฑฐ ์คํจ" | |
| except Exception as e: | |
| return None, f"๋ฐฐ๊ฒฝ ์ ๊ฑฐ ์ค๋ฅ: {str(e)}" | |
| def upscale_with_clarity(image_path): | |
| """ํ์ง ๊ฐ์ ์ ์ค์ผ์ผ๋ฌ""" | |
| if not REPLICATE_API_TOKEN: | |
| return None, "Replicate API ํ ํฐ์ด ํ์ํฉ๋๋ค." | |
| try: | |
| output = replicate.run( | |
| "philz1337x/clarity-upscaler:dfad41707589d68ecdccd1dfa600d55a208f9310748e44bfe35b4a6291453d5e", | |
| input={"image": open(image_path, "rb")} | |
| ) | |
| # output์ ๋ฆฌ์คํธ์ด๋ฏ๋ก ์ฒซ ๋ฒ์งธ ํญ๋ชฉ ์ฌ์ฉ | |
| response = requests.get(output[0]) | |
| if response.status_code == 200: | |
| return Image.open(io.BytesIO(response.content)), "ํ์ง ๊ฐ์ ์๋ฃ" | |
| else: | |
| return None, "ํ์ง ๊ฐ์ ์คํจ" | |
| except Exception as e: | |
| return None, f"ํ์ง ๊ฐ์ ์ค๋ฅ: {str(e)}" | |
| def change_product_angle(image_path): | |
| """์นด๋ฉ๋ผ ์์น๋ฅผ ๋ฐ๊ฟ์ ๋ค๋ฅธ ์ต๊ธ๋ก ์ดฌ์""" | |
| if not REPLICATE_API_TOKEN: | |
| return None, "Replicate API ํ ํฐ์ด ํ์ํฉ๋๋ค." | |
| try: | |
| # Gen4 Image๋ก ์นด๋ฉ๋ผ ์์น ๋ณ๊ฒฝ (ํ์ผ ์ง์ ์ ๋ก๋) | |
| angle_prompt = "Professional product photography of @product from 45-degree side angle, three-quarter view, diagonal perspective, different camera position, clean background" | |
| with open(image_path, "rb") as image_file: | |
| output = replicate.run( | |
| "runwayml/gen4-image", | |
| input={ | |
| "prompt": angle_prompt, | |
| "aspect_ratio": "1:1", | |
| "resolution": "1080p", | |
| "reference_images": [image_file], | |
| "reference_tags": ["product"] | |
| } | |
| ) | |
| response = requests.get(output) | |
| if response.status_code == 200: | |
| return Image.open(io.BytesIO(response.content)), "์นด๋ฉ๋ผ ์ต๊ธ ๋ณ๊ฒฝ ์๋ฃ (Gen4)" | |
| else: | |
| return None, "์นด๋ฉ๋ผ ์ต๊ธ ๋ณ๊ฒฝ ์คํจ" | |
| except Exception as e: | |
| return None, f"์นด๋ฉ๋ผ ์ต๊ธ ๋ณ๊ฒฝ ์ค๋ฅ: {str(e)}" | |
| def add_shadow_only(image_path): | |
| """๋ฐฐ๊ฒฝ ์ ๊ฑฐ๋ ์ํ์ ๊ทธ๋ฆผ์๋ง ์ถ๊ฐ (์์ ํ ํฐ์ ๋ฐฐ๊ฒฝ)""" | |
| if not REPLICATE_API_TOKEN: | |
| return None, "Replicate API ํ ํฐ์ด ํ์ํฉ๋๋ค." | |
| try: | |
| # Gen4 Image๋ก ๊ทธ๋ฆผ์ ์ถ๊ฐ (ํ์ผ ์ง์ ์ ๋ก๋) | |
| shadow_prompt = "Professional product photography of @product on pure white background with natural soft drop shadow, clean white backdrop, subtle shadow effect, e-commerce style" | |
| with open(image_path, "rb") as image_file: | |
| output = replicate.run( | |
| "runwayml/gen4-image", | |
| input={ | |
| "prompt": shadow_prompt, | |
| "aspect_ratio": "1:1", | |
| "resolution": "1080p", | |
| "reference_images": [image_file], | |
| "reference_tags": ["product"] | |
| } | |
| ) | |
| response = requests.get(output) | |
| if response.status_code == 200: | |
| return Image.open(io.BytesIO(response.content)), "๊ทธ๋ฆผ์ ์ถ๊ฐ ์๋ฃ (Gen4)" | |
| else: | |
| return None, "๊ทธ๋ฆผ์ ์ถ๊ฐ ์คํจ" | |
| except Exception as e: | |
| return None, f"๊ทธ๋ฆผ์ ์ถ๊ฐ ์ค๋ฅ: {str(e)}" | |
| def process_image(image, remove_bg, upscale_quality): | |
| """๋ฉ์ธ ์ฒ๋ฆฌ ํจ์""" | |
| if image is None: | |
| return None, "์ด๋ฏธ์ง๋ฅผ ์ ๋ก๋ํด์ฃผ์ธ์." | |
| try: | |
| result_image = image.copy() | |
| status_messages = [] | |
| # 1๋จ๊ณ: ์ํ ๊ฐ๋ ๋ณ๊ฒฝ | |
| temp_path = upload_image_to_temp_url(result_image) | |
| if temp_path: | |
| angled_img, angle_msg = change_product_angle(temp_path) | |
| if angled_img: | |
| result_image = angled_img | |
| status_messages.append(f"โ {angle_msg}") | |
| else: | |
| status_messages.append(f"โ {angle_msg}") | |
| os.unlink(temp_path) | |
| # 2๋จ๊ณ: ๋ฐฐ๊ฒฝ ์ ๊ฑฐ (๋๋ผ) | |
| if remove_bg: | |
| temp_path = upload_image_to_temp_url(result_image) | |
| if temp_path: | |
| bg_removed_img, bg_msg = remove_background_with_ai(temp_path) | |
| if bg_removed_img: | |
| result_image = bg_removed_img | |
| status_messages.append(f"โ {bg_msg}") | |
| else: | |
| status_messages.append(f"โ {bg_msg}") | |
| os.unlink(temp_path) | |
| # 3๋จ๊ณ: ๊ทธ๋ฆผ์๋ง ์ถ๊ฐ (์์ ํ ํฐ์ ๋ฐฐ๊ฒฝ) | |
| temp_path = upload_image_to_temp_url(result_image) | |
| if temp_path: | |
| shadow_img, shadow_msg = add_shadow_only(temp_path) | |
| if shadow_img: | |
| result_image = shadow_img | |
| status_messages.append(f"โ {shadow_msg}") | |
| else: | |
| status_messages.append(f"โ {shadow_msg}") | |
| os.unlink(temp_path) | |
| # 4๋จ๊ณ: ํ์ง ๊ฐ์ (์ด๋ฏธ์ง ์์ฑ ํ) | |
| if upscale_quality: | |
| temp_path = upload_image_to_temp_url(result_image) | |
| if temp_path: | |
| upscaled_img, upscale_msg = upscale_with_clarity(temp_path) | |
| if upscaled_img: | |
| result_image = upscaled_img | |
| status_messages.append(f"โ {upscale_msg}") | |
| else: | |
| status_messages.append(f"โ {upscale_msg}") | |
| os.unlink(temp_path) | |
| # 5๋จ๊ณ: ์ต์ข ํฌ๊ธฐ ์กฐ์ | |
| result_image = result_image.resize((1000, 1000), Image.Resampling.LANCZOS) | |
| status_messages.append("โ 1000x1000 ํฌ๊ธฐ ์กฐ์ ์๋ฃ") | |
| return result_image, "\n".join(status_messages) | |
| except Exception as e: | |
| return None, f"์ฒ๋ฆฌ ์ค ์ค๋ฅ: {str(e)}" | |
| # Gradio ์ธํฐํ์ด์ค | |
| def create_interface(): | |
| with gr.Blocks(title="์ฟ ํก ์ธ๋ค์ผ ์์ฑ๊ธฐ", theme=gr.themes.Soft()) as iface: | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| # ์ด๋ฏธ์ง ์ ๋ก๋ | |
| input_image = gr.Image( | |
| label="์ํ ์ด๋ฏธ์ง ์ ๋ก๋", | |
| type="pil", | |
| height=400 | |
| ) | |
| # ์ ํ ๊ธฐ๋ฅ 2๊ฐ์ง | |
| with gr.Group(): | |
| remove_bg = gr.Checkbox( | |
| label="๋ฐฐ๊ฒฝ ์ ๊ฑฐ", | |
| value=True, | |
| info="AI๋ก ๋ฐฐ๊ฒฝ์ ์๋ ์ ๊ฑฐํฉ๋๋ค" | |
| ) | |
| upscale_quality = gr.Checkbox( | |
| label="ํ์ง ๊ฐ์ ๊ธฐ", | |
| value=True, | |
| info="AI๋ก ํ์ง์ ํฅ์์ํต๋๋ค" | |
| ) | |
| # ์คํ ๋ฒํผ | |
| process_btn = gr.Button("๐ ์ธ๋ค์ผ ์์ฑ", variant="primary", size="lg") | |
| with gr.Column(scale=1): | |
| # ์ถ๋ ฅ ์ด๋ฏธ์ง | |
| output_image = gr.Image( | |
| label="์ฟ ํก ์ธ๋ค์ผ ๊ฒฐ๊ณผ", | |
| height=400 | |
| ) | |
| status_output = gr.Textbox( | |
| label="์ฒ๋ฆฌ ์ํ", | |
| lines=6, | |
| max_lines=10 | |
| ) | |
| # ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ | |
| process_btn.click( | |
| process_image, | |
| inputs=[input_image, remove_bg, upscale_quality], | |
| outputs=[output_image, status_output] | |
| ) | |
| return iface | |
| # ์ฑ ์คํ | |
| if __name__ == "__main__": | |
| app = create_interface() | |
| app.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=True, | |
| show_error=True | |
| ) |