File size: 2,048 Bytes
228add1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
"""
Image loading service.
Handles loading images from file upload, URL, and base64.
"""

import base64
from io import BytesIO

import requests
from PIL import Image

from backend.app.core.config import get_settings
from backend.app.core.logging import logger


def load_image_from_upload(file_bytes: bytes) -> Image.Image:
    """Load image from uploaded file bytes."""
    try:
        image = Image.open(BytesIO(file_bytes)).convert('RGB')
        return image
    except Exception as e:
        logger.error(f"Failed to load uploaded image: {e}")
        raise ValueError(f"Invalid image file: {e}")


def load_image_from_url(url: str) -> Image.Image:
    """Load image from a URL."""
    settings = get_settings()
    try:
        response = requests.get(url, timeout=settings.url_timeout, stream=True)
        response.raise_for_status()

        # Check content length
        content_length = response.headers.get('Content-Length')
        if content_length and int(content_length) > settings.max_image_size_mb * 1024 * 1024:
            raise ValueError(f"Image too large (max {settings.max_image_size_mb}MB)")

        image = Image.open(BytesIO(response.content)).convert('RGB')
        return image
    except requests.RequestException as e:
        logger.error(f"Failed to fetch image from URL: {e}")
        raise ValueError(f"Could not fetch image from URL: {e}")
    except Exception as e:
        logger.error(f"Failed to load image from URL: {e}")
        raise ValueError(f"Invalid image from URL: {e}")


def load_image_from_base64(b64_string: str) -> Image.Image:
    """Load image from base64-encoded string."""
    try:
        # Remove data URI prefix if present
        if ',' in b64_string:
            b64_string = b64_string.split(',', 1)[1]

        image_bytes = base64.b64decode(b64_string)
        image = Image.open(BytesIO(image_bytes)).convert('RGB')
        return image
    except Exception as e:
        logger.error(f"Failed to load base64 image: {e}")
        raise ValueError(f"Invalid base64 image: {e}")