Spaces:
Running
Running
| import base64 | |
| import time | |
| from io import BytesIO | |
| from PIL import Image | |
| from loguru import logger | |
| def crop_image(img: Image, new_size: tuple[int, int]) -> Image: | |
| """ | |
| Crop an image to the specified size, maintaining the aspect ratio. | |
| :param img: The image to crop. | |
| :param new_size: The target size of the cropped image. | |
| :return: The cropped image. | |
| """ | |
| width, height = img.size | |
| target_width, target_height = new_size | |
| aspect_ratio = width / height | |
| target_aspect_ratio = target_width / target_height | |
| if aspect_ratio > target_aspect_ratio: | |
| new_height = target_height | |
| new_width = int(aspect_ratio * new_height) | |
| else: | |
| new_width = target_width | |
| new_height = int(new_width / aspect_ratio) | |
| img = img.resize((new_width, new_height), Image.Resampling.LANCZOS) | |
| left = (new_width - target_width) / 2 | |
| top = (new_height - target_height) / 2 | |
| right = (new_width + target_width) / 2 | |
| bottom = (new_height + target_height) / 2 | |
| return img.crop((left, top, right, bottom)) | |
| def encode_image_to_webp_base64(filepath): | |
| """ | |
| Encodes an image file to WEBP and then to a Base64 string. | |
| :param filepath: Path to the image file | |
| :return: Base64 encoded string of the WEBP image | |
| :raises ValueError: If filepath is None or other issues occur during encoding | |
| """ | |
| start_time = time.time() | |
| if filepath is None: | |
| raise ValueError("File path is None.") | |
| try: | |
| pil_image = Image.open(filepath) | |
| if pil_image.mode == 'RGBA': | |
| pil_image = pil_image.convert('RGB') | |
| buffered = BytesIO() | |
| pil_image.save(buffered, format="WEBP") | |
| base64_image = base64.b64encode(buffered.getvalue()).decode('utf-8') | |
| return base64_image | |
| except Exception as e: | |
| raise ValueError(f"Failed to encode image to WEBP base64: {str(e)}") | |
| finally: | |
| end_time = time.time() | |
| elapsed_time = end_time - start_time | |
| logger.info(f"Encoding image to WebP and Base64 spent {elapsed_time:.2f} seconds to process.") | |
| def encode_webp_to_base64(image_file): | |
| """ | |
| Encodes a WEBP image file (from HTTP upload) directly to a Base64 string. | |
| :param image_file: InMemoryUploadedFile object containing the WEBP image | |
| :return: Base64 encoded string of the WEBP image | |
| :raises ValueError: If image_file is None or other issues occur during encoding | |
| """ | |
| start_time = time.time() | |
| if image_file is None: | |
| raise ValueError("Image file is None.") | |
| try: | |
| # Ensure that the file is read as binary data | |
| base64_image = base64.b64encode(image_file.read()).decode('utf-8') | |
| return base64_image | |
| except Exception as e: | |
| raise ValueError(f"Failed to encode WEBP image to Base64: {str(e)}") | |
| finally: | |
| end_time = time.time() | |
| elapsed_time = end_time - start_time | |
| logger.info(f"Encoding image to Base64 spent {elapsed_time:.2f} seconds to process.") | |