Files
Home_assistant/backend/app/vision/preprocess.py
T
2026-06-16 04:38:23 +00:00

54 lines
1.5 KiB
Python

from __future__ import annotations
import io
from dataclasses import dataclass
from PIL import Image, ImageOps
from app.config import get_settings
@dataclass
class PreparedImage:
jpeg_bytes: bytes
width: int
height: int
original_bytes: int
compressed_bytes: int
mime: str = "image/jpeg"
def to_meta(self) -> dict[str, int | str]:
return {
"mime": self.mime,
"width": self.width,
"height": self.height,
"original_bytes": self.original_bytes,
"compressed_bytes": self.compressed_bytes,
}
def prepare_image(raw_bytes: bytes) -> PreparedImage:
settings = get_settings()
max_edge = max(256, int(settings.vision_max_edge_px))
quality = max(40, min(95, int(settings.vision_jpeg_quality)))
with Image.open(io.BytesIO(raw_bytes)) as img:
img = ImageOps.exif_transpose(img)
img = img.convert("RGB")
width, height = img.size
if max(width, height) > max_edge:
img.thumbnail((max_edge, max_edge), Image.Resampling.LANCZOS)
width, height = img.size
buffer = io.BytesIO()
img.save(buffer, format="JPEG", quality=quality, optimize=True)
jpeg_bytes = buffer.getvalue()
return PreparedImage(
jpeg_bytes=jpeg_bytes,
width=width,
height=height,
original_bytes=len(raw_bytes),
compressed_bytes=len(jpeg_bytes),
)