summaryrefslogtreecommitdiff
path: root/src/ollama_web/tools/helper/image.py
blob: e89a96faa5fd7c289123407e51bbdb1f64527177 (plain)
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
62
63
64
65
"""Image preprocessing helpers for ollama vision models."""

from __future__ import annotations

import io
from pathlib import Path

from PIL import Image

from ...config import settings

Image.MAX_IMAGE_PIXELS = settings.max_image_pixels


_IMAGE_FORMATS: dict[str, str] = {
    "png": "PNG",
    "jpg": "JPEG",
    "jpeg": "JPEG",
    "gif": "GIF",
    "bmp": "BMP",
    "webp": "WEBP",
    "tif": "TIFF",
    "tiff": "TIFF",
}


def _format_from_name(name: str) -> str:
    ext = Path(name).suffix.lstrip(".").lower()
    return _IMAGE_FORMATS.get(ext, "JPEG")


def resize_image(
    data: bytes,
    name: str = "image.jpg",
    max_dimension: int = 1024,
    quality: int = 85,
) -> bytes:
    """Resize and re-encode an image to reduce payload size for ollama."""
    if not data:
        return data

    try:
        with Image.open(io.BytesIO(data)) as img:
            if img.width * img.height > settings.max_image_pixels:
                return data
            processed = img.convert("RGB")

            width, height = processed.size
            if width > max_dimension or height > max_dimension:
                ratio = min(max_dimension / width, max_dimension / height)
                new_size = (int(width * ratio), int(height * ratio))
                processed = processed.resize(new_size, Image.Resampling.LANCZOS)

            fmt = _format_from_name(name)
            output = io.BytesIO()
            save_kwargs: dict[str, object] = {}
            if fmt == "JPEG":
                save_kwargs["quality"] = quality
                save_kwargs["optimize"] = True
            elif fmt == "WEBP":
                save_kwargs["quality"] = quality
            processed.save(output, format=fmt, **save_kwargs)
            return output.getvalue()
    except Exception:  # noqa: BLE001
        return data