Spaces:
Sleeping
Sleeping
| import requests | |
| import zipfile | |
| import tempfile | |
| from PIL import Image | |
| from io import BytesIO | |
| from rembg import remove | |
| # ๊ฐ์ข ์ค์ ๊ฐ | |
| BACKGROUND_IMAGE_MAX_SIZE = 1024 # ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง์ ํฌ๊ธฐ | |
| PRODUCT_IMAGE_MAX_SIZE = 650 # ๋ฐฐ๊ฒฝ์ด ์ ๊ฑฐ๋ ์ ํ ์ด๋ฏธ์ง์ ํฌ๊ธฐ | |
| TYPD_B_MARGIN = 15 | |
| TYPE_C_MARGIN_1, TYPE_C_MARGIN_2 = 15, 45 # (1=๊ฐ์ด๋ฐ ๋๊ฐ์ ๋ง์ง, 2= ์ค์ ํ๊ฐ์ top ๋ง์ง) | |
| def download_image(image_url: str) -> Image.Image: | |
| # ์ด๋ฏธ์ง ๋ค์ด๋ก๋ | |
| response = requests.get(image_url) | |
| if response.status_code == 200: | |
| original_image = Image.open(BytesIO(response.content)) | |
| return original_image | |
| else: | |
| raise Exception(f"Failed to download image. Status code: {response.status_code}") | |
| def remove_background(image: Image.Image) -> Image.Image: | |
| # ์ด๋ฏธ์ง ๋๋ผ๋ฐ๊ธฐ | |
| try: | |
| removebg_image = remove( | |
| image, | |
| post_process_mask=True, | |
| alpha_matting=True, | |
| alpha_matting_foreground_threshold=270, | |
| alpha_matting_background_threshold=30, | |
| alpha_matting_erode_size=15) | |
| return removebg_image | |
| except Exception as e: | |
| print(f"Failed to remove background: {e}") | |
| return None | |
| def crop_image(image: Image.Image) -> Image.Image: | |
| # ์ด๋ฏธ์ง ํฌ๋กญ | |
| try: | |
| # ์ํ ์ฑ๋์ ์ฌ์ฉํ์ฌ ์ด๋ฏธ์ง์ ๊ฒฝ๊ณ ์์ญ ์ฐพ๊ธฐ | |
| bbox = image.getbbox() | |
| if bbox: | |
| # ๊ฒฝ๊ณ ์์๋ก ์ด๋ฏธ์ง ํฌ๋กญ | |
| cropped_image = image.crop(bbox) | |
| return cropped_image | |
| else: | |
| print("No bounding box found.") | |
| return image | |
| except Exception as e: | |
| print(f"Failed to crop image: {e}") | |
| return None | |
| def resize_image(image: Image.Image, max_size: int) -> Image.Image: | |
| # ์ด๋ฏธ์ง ํฌ๊ธฐ ์กฐ์ | |
| try: | |
| # ์ด๋ฏธ์ง์ ํ์ฌ ๋๋น์ ๋์ด ๊ฐ์ ธ์ค๊ธฐ | |
| width, height = image.size | |
| # ๋๋น์ ๋์ด ์ค ๋ ํฐ ์ชฝ์ ๋น์จ์ ๋ง์ถฐ ํฌ๊ธฐ๋ฅผ ์กฐ์ | |
| if width > height: | |
| new_width = max_size | |
| new_height = int((max_size / width) * height) | |
| else: | |
| new_height = max_size | |
| new_width = int((max_size / height) * width) | |
| resized_image = image.resize((new_width, new_height)) | |
| return resized_image | |
| except Exception as e: | |
| print(f"Failed to resize image: {e}") | |
| return None | |
| def paste_to_background_type_a(background: Image.Image, product: Image.Image) -> Image.Image: | |
| try: | |
| bg_width, bg_height = background.size | |
| product_width, product_height = product.size | |
| # ์ ํ ์ด๋ฏธ์ง๋ฅผ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง ์ค์์ ์์น์ํค๊ธฐ (์์ ์คํ์ ํ์ฉ) | |
| offset = ((bg_width - product_width) // 2, (bg_height - product_height) // 2) | |
| # ์ํ ์ฑ๋์ ๊ณ ๋ คํ์ฌ ํฉ์ฑ (์์ ์คํ์ ์ง์) | |
| background.paste(product, offset, mask=product) | |
| return background | |
| except Exception as e: | |
| print(f"Failed to paste product image to background: {e}") | |
| return None | |
| def paste_to_background_type_b(background: Image.Image, product: Image.Image, margin: int = 10) -> Image.Image: | |
| try: | |
| bg_width, bg_height = background.size | |
| product_width, product_height = product.size | |
| # ๋ ์ ํ ์ด๋ฏธ์ง๋ฅผ ์ํ ์ ์ฒด ๋๋น ๊ณ์ฐ (์์ ๊ฐ ํ์ฉ) | |
| total_width = (product_width * 2) + margin | |
| # ์ฒซ ๋ฒ์งธ ์ ํ ์ด๋ฏธ์ง์ ์ผ์ชฝ ์๋จ ์ขํ ๊ณ์ฐ (์์ ์คํ์ ํ์ฉ) | |
| left_offset = (bg_width - total_width) // 2 | |
| top_offset = (bg_height - product_height) // 2 | |
| # ์ฒซ ๋ฒ์งธ ์ ํ ์ด๋ฏธ์ง ํฉ์ฑ | |
| background.paste(product, (left_offset, top_offset), mask=product) | |
| # ๋ ๋ฒ์งธ ์ ํ ์ด๋ฏธ์ง์ ์ผ์ชฝ ์๋จ ์ขํ ๊ณ์ฐ | |
| right_offset = left_offset + product_width + margin | |
| # ๋ ๋ฒ์งธ ์ ํ ์ด๋ฏธ์ง ํฉ์ฑ | |
| background.paste(product, (right_offset, top_offset), mask=product) | |
| return background | |
| except Exception as e: | |
| print(f"Failed to paste product images to background: {e}") | |
| return None | |
| def paste_to_background_type_c(background: Image.Image, product: Image.Image, margin: int = 10, top_margin: int = 15) -> Image.Image: | |
| try: | |
| bg_width, bg_height = background.size | |
| product_width, product_height = product.size | |
| # ์๋ ๋ ์ ํ ์ด๋ฏธ์ง๋ฅผ ๋ฐฐ์น | |
| background_with_two_products = paste_to_background_type_b(background, product, margin) | |
| # ์ค์ ์๋จ์ ์์นํ ์ ํ ์ด๋ฏธ์ง์ ์คํ์ ๊ณ์ฐ (์์ ์คํ์ ํ์ฉ) | |
| center_offset_x = (bg_width - product_width) // 2 | |
| center_offset_y = ((bg_height - product_height) // 2) + top_margin | |
| # ์ธ ๋ฒ์งธ ์ ํ ์ด๋ฏธ์ง ํฉ์ฑ (์ค์ ์๋จ) | |
| background_with_two_products.paste(product, (center_offset_x, center_offset_y), mask=product) | |
| return background_with_two_products | |
| except Exception as e: | |
| print(f"Failed to paste product images to background: {e}") | |
| return None | |
| def create_zip_file(images: list) -> str: | |
| # ์์ ํ์ผ ์์ฑ | |
| with tempfile.NamedTemporaryFile(delete=False, suffix=".zip") as temp_zip: | |
| with zipfile.ZipFile(temp_zip, 'w', zipfile.ZIP_DEFLATED) as zipf: | |
| for i, image in enumerate(images): | |
| # ์ด๋ฏธ์ง๋ฅผ ๋ฉ๋ชจ๋ฆฌ ๋ฒํผ์ ์ ์ฅ | |
| image_buffer = BytesIO() | |
| image.save(image_buffer, format="PNG") | |
| image_buffer.seek(0) | |
| # ๋ฒํผ ๋ด์ฉ์ ZIP ํ์ผ์ ์ถ๊ฐ | |
| zipf.writestr(f"image_{i + 1}.png", image_buffer.getvalue()) | |
| # ์์ ํ์ผ์ ๊ฒฝ๋ก๋ฅผ ๋ฐํ | |
| temp_zip_path = temp_zip.name | |
| return temp_zip_path | |
| def image_processing(background_image: Image.Image, product_image_url: str, product_image_size: int = 650): | |
| # ์ด๋ฏธ์ง ๋ค์ด๋ก๋ | |
| original_image = download_image(product_image_url) | |
| # ์ด๋ฏธ์ง ๋๋ผ๋ฐ๊ธฐ | |
| removebg_image = remove_background(original_image) | |
| # ์ด๋ฏธ์ง ํฌ๋กญ | |
| cropped_image = crop_image(removebg_image) | |
| # ํฌ๋กญ๋ ์ด๋ฏธ์ง ์ํ๋ ์ฌ์ด์ฆ๋ก resize | |
| resized_image = resize_image(cropped_image, product_image_size) | |
| # type_a ํฉ์ฑ | |
| type_a_image = paste_to_background_type_a(background_image.copy(), resized_image) | |
| type_b_image = paste_to_background_type_b(background_image.copy(), resized_image, TYPD_B_MARGIN) | |
| type_c_image = paste_to_background_type_c(background_image.copy(), resized_image, TYPE_C_MARGIN_1, TYPE_C_MARGIN_2) | |
| # ๊ฒฐ๊ณผ ์ด๋ฏธ์ง ๋ฐํ | |
| return type_a_image, type_b_image, type_c_image | |
| def image_processing_single(background_image: Image.Image, product_image_url: str, product_image_size: int = 650): | |
| # ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง ํฌ๊ธฐ ์กฐ์ | |
| background_image = background_image.resize((BACKGROUND_IMAGE_MAX_SIZE, BACKGROUND_IMAGE_MAX_SIZE)) | |
| # ์ด๋ฏธ์ง ํ๋ก์ธ์ฑ | |
| type_a_image, type_b_image, type_c_image = image_processing(background_image, product_image_url, product_image_size) | |
| # ๊ฒฐ๊ณผ ์ด๋ฏธ์ง ๋ฐํ | |
| image_list = [type_a_image, type_b_image, type_c_image] | |
| zip_file_path = create_zip_file(image_list) | |
| return image_list, zip_file_path | |
| def image_processing_batch(background_image: Image.Image, product_image_url_file_path: str, product_image_size: int = 650): | |
| # ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง ํฌ๊ธฐ ์กฐ์ | |
| background_image = background_image.resize((BACKGROUND_IMAGE_MAX_SIZE, BACKGROUND_IMAGE_MAX_SIZE)) | |
| # file to url | |
| def file_to_list(file_path: str) -> list: | |
| # ํ์ผ์ ์ด๊ณ ์ฝ๊ธฐ | |
| with open(file_path, "r") as f: | |
| # ํ์ผ ๋ด์ฉ์ ์ฝ์ด์ ์ค๋ฐ๊ฟ(์ํฐ)๋ก ๊ตฌ๋ถ๋ ๊ฐ URL์ ๋ฆฌ์คํธ๋ก ๋ณํ | |
| content = f.read() | |
| # ์ค๋ฐ๊ฟ์ผ๋ก URL ๋ถ๋ฆฌ | |
| url_list = [url.strip() for url in content.splitlines() if url.strip()] | |
| return url_list | |
| product_image_url_list = file_to_list(product_image_url_file_path) | |
| preview_image_list, image_list = [], [] | |
| for idx, product_image_url in enumerate(product_image_url_list): | |
| type_a_image, type_b_image, type_c_image = image_processing(background_image, product_image_url, product_image_size) | |
| image_list.append(type_a_image) | |
| image_list.append(type_b_image) | |
| image_list.append(type_c_image) | |
| if idx == 0: | |
| preview_image_list = [type_a_image, type_b_image, type_c_image] | |
| zip_file_path = create_zip_file(image_list) | |
| return preview_image_list, zip_file_path | |