From ba6fa78096a14207da02434a77885957769a5b4e Mon Sep 17 00:00:00 2001 From: James Huang Date: Mon, 7 Sep 2026 02:44:37 +0200 Subject: [PATCH] fix: letterbox image to exact target size when fitscreen is false image_to_rgb565 with fitscreen=False used only PIL thumbnail(), which preserves aspect ratio and returns an image smaller than the requested box whenever the source aspect differs from the box (e.g. a square cover pushed into a wide 400x160 object). The plate decodes the RGB565 payload using the width in the header as the row stride, so a pushed image narrower than the object box renders doubled/split (a '1.5 image') instead of centered. Letterbox the thumbnail onto a black canvas at the exact target size so the pushed width always matches the object width. Sources smaller than the box keep the existing no-upscale behaviour (unchanged output). --- custom_components/openhasp/image.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/custom_components/openhasp/image.py b/custom_components/openhasp/image.py index 18a2d84..d8cf4b2 100644 --- a/custom_components/openhasp/image.py +++ b/custom_components/openhasp/image.py @@ -33,6 +33,16 @@ def image_to_rgb565(in_image, size, fitscreen): 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((width, height), Image.LANCZOS) + # Letterbox to the exact target size so the pushed image width + # always matches the plate object width. The plate decodes RGB565 + # rows using the header width, so a pushed image narrower than + # the box (e.g. a square source into a wide box) renders doubled + # or split instead of centered. + canvas = Image.new("RGB", (width, height), (0, 0, 0)) + canvas.paste( + im.convert("RGB"), ((width - im.width) // 2, (height - im.height) // 2) + ) + im = canvas else: im = ImageOps.fit( im, (width, height), method=3, bleed=0.0, centering=(0.5, 0.5)