Files
hassos_config/custom_components/openhasp/image.py
2022-12-20 21:26:47 +01:00

81 lines
2.3 KiB
Python

"""Image processing and serving functions."""
import logging
import struct
import tempfile
from PIL import Image
from aiohttp import hdrs, web
from homeassistant.components.http.static import CACHE_HEADERS
from homeassistant.components.http.view import HomeAssistantView
import requests
from .const import DATA_IMAGES, DOMAIN
_LOGGER = logging.getLogger(__name__)
def image_to_rgb565(in_image, size):
"""Transform image to rgb565 format according to LVGL requirements."""
try:
if in_image.startswith("http"):
im = Image.open(requests.get(in_image, stream=True).raw)
else:
im = Image.open(in_image)
except Exception:
_LOGGER.error("Failed to open %s", in_image)
return None
original_width, original_height = im.size
width, height = size
width = min(w for w in [width, original_width] if w is not None and w > 0)
height = min(h for h in [height, original_height] if h is not None and h > 0)
im.thumbnail((height, width), Image.ANTIALIAS)
width, height = im.size # actual size after resize
out_image = tempfile.NamedTemporaryFile(mode="w+b")
out_image.write(struct.pack("I", height << 21 | width << 10 | 4))
img = im.convert("RGB")
for pix in img.getdata():
r = (pix[0] >> 3) & 0x1F
g = (pix[1] >> 2) & 0x3F
b = (pix[2] >> 3) & 0x1F
out_image.write(struct.pack("H", (r << 11) | (g << 5) | b))
_LOGGER.debug("image_to_rgb565 out_image: %s", out_image.name)
out_image.flush()
return out_image
class ImageServeView(HomeAssistantView):
"""View to download images."""
url = "/api/openhasp/serve/{image_id}"
name = "api:openhasp:serve"
requires_auth = False
def __init__(self) -> None:
"""Initialize image serve view."""
async def get(self, request: web.Request, image_id: str):
"""Serve image."""
hass = request.app["hass"]
target_file = hass.data[DOMAIN][DATA_IMAGES].get(image_id)
if target_file is None:
_LOGGER.error("Unknown image_id %s", image_id)
return web.HTTPNotFound()
_LOGGER.debug("Get Image %s form %s", image_id, target_file.name)
return web.FileResponse(
target_file.name, headers={**CACHE_HEADERS, hdrs.CONTENT_TYPE: "image/bmp"}
)