|
from PIL import Image |
|
from io import BytesIO |
|
import requests |
|
import base64 |
|
from typing import Union, Tuple |
|
|
|
def resize_image(image_input: Union[str, BytesIO], target_size: Tuple[int, int], return_format: str = "base64") -> str: |
|
""" |
|
Resize an image to the target size while maintaining aspect ratio. |
|
|
|
Args: |
|
image_input: URL, file path, base64 string, or BytesIO object |
|
target_size: Tuple (width, height) for the target size |
|
return_format: Format to return the image in ("base64" or "pil") |
|
|
|
Returns: |
|
Base64 encoded string of the resized image or PIL Image object |
|
""" |
|
|
|
if isinstance(image_input, str): |
|
if image_input.startswith(('http://', 'https://')): |
|
|
|
response = requests.get(image_input, timeout=10) |
|
response.raise_for_status() |
|
image = Image.open(BytesIO(response.content)) |
|
elif image_input.startswith('data:image'): |
|
|
|
base64_data = image_input.split(',')[1] |
|
image = Image.open(BytesIO(base64.b64decode(base64_data))) |
|
elif ';base64,' not in image_input and len(image_input) > 500: |
|
|
|
image = Image.open(BytesIO(base64.b64decode(image_input))) |
|
else: |
|
|
|
image = Image.open(image_input) |
|
elif isinstance(image_input, BytesIO): |
|
image = Image.open(image_input) |
|
else: |
|
raise ValueError("Unsupported image input type") |
|
|
|
|
|
aspect_ratio = min(target_size[0] / image.width, target_size[1] / image.height) |
|
|
|
|
|
new_size = (int(image.width * aspect_ratio), int(image.height * aspect_ratio)) |
|
|
|
|
|
resized_image = image.resize(new_size, Image.LANCZOS) |
|
|
|
|
|
if return_format.lower() == "base64": |
|
buffer = BytesIO() |
|
resized_image.save(buffer, format="PNG") |
|
return base64.b64encode(buffer.getvalue()).decode('utf-8') |
|
else: |
|
return resized_image |