|
from PIL import Image |
|
import io |
|
from pathlib import Path |
|
import time |
|
import traceback |
|
from typing import Union, Optional |
|
from .api_utils import upload_to_freeimage |
|
|
|
def prepare_image(image: Union[str, bytes, Image.Image, None], status_tracker) -> Optional[str]: |
|
""" |
|
Prepare an image for use with LumaAI by resizing and uploading to CDN. |
|
|
|
Args: |
|
image: Input image (can be path, bytes, or PIL Image) |
|
status_tracker: StatusTracker instance for progress updates |
|
|
|
Returns: |
|
Optional[str]: CDN URL of the prepared image, or None if no image provided |
|
|
|
Raises: |
|
Exception: If image preparation fails |
|
""" |
|
if image is None: |
|
return None |
|
|
|
try: |
|
status_tracker.update_message("Preparing your image for its big moment...", 0.01) |
|
|
|
|
|
if isinstance(image, str): |
|
image = Image.open(image) |
|
elif isinstance(image, bytes): |
|
image = Image.open(io.BytesIO(image)) |
|
elif not isinstance(image, Image.Image): |
|
raise Exception("That doesn't look like an image (unless I need glasses)") |
|
|
|
|
|
image = image.resize((512, 512), Image.Resampling.LANCZOS) |
|
status_tracker.add_step("Image resized to 512x512", 0.02) |
|
|
|
|
|
if image.mode not in ('RGB', 'RGBA'): |
|
image = image.convert('RGB') |
|
|
|
|
|
temp_dir = Path("temp") |
|
temp_dir.mkdir(exist_ok=True) |
|
temp_path = temp_dir / f"temp_image_{int(time.time())}.png" |
|
image.save(str(temp_path), format='PNG', optimize=True) |
|
|
|
|
|
try: |
|
cdn_url = upload_to_freeimage(temp_path, status_tracker) |
|
|
|
|
|
if temp_path.exists(): |
|
temp_path.unlink() |
|
|
|
return cdn_url |
|
except Exception as e: |
|
|
|
if temp_path.exists(): |
|
temp_path.unlink() |
|
raise Exception(f"Image upload failed: {str(e)}") |
|
|
|
except Exception as e: |
|
print(f"Error preparing image: {str(e)}") |
|
print(traceback.format_exc()) |
|
raise Exception(f"Image preparation failed: {str(e)}") |
|
|