fix(artwork): letterbox images and back alpha art with black

This commit is contained in:
beefcarver committed 2026-11-03 18:44:47 -05:00
1 parent 50a9a735f7
commit e14a349c2d
2 files changed
+85 -12

No files matched your search

+63 -6
View File
@@ -9,9 +9,20 @@ from PIL import Image
from beefy_player import artwork
def png_bytes(size=(400, 200)) -> bytes:
def png_bytes(size=(400, 200), alpha: int = 180) -> bytes:
buffer = BytesIO()
Image.new("RGBA", size, (20, 180, 220, 180)).save(buffer, format="PNG")
Image.new("RGBA", size, (20, 180, 220, alpha)).save(buffer, format="PNG")
return buffer.getvalue()
def ink_bbox(image: Image.Image):
"""Where the artwork itself is, ignoring transparent or black padding."""
return image.convert("RGB").getbbox()
def opaque_png_bytes(size=(400, 200)) -> bytes:
buffer = BytesIO()
Image.new("RGB", size, (20, 180, 220)).save(buffer, format="PNG")
return buffer.getvalue()
@@ -35,12 +46,58 @@ def test_protocol_detection() -> None:
assert artwork.detect_protocol({"SOMAFM_IMAGES": "0"}) is None
def test_fit_image_crops_to_the_cell_box() -> None:
fitted = artwork.fit_image(png_bytes(), 13, 8)
def test_fit_image_letterboxes_inside_the_cell_box() -> None:
fitted = artwork.fit_image(png_bytes((400, 200)), 13, 8)
assert fitted is not None
cell_width, cell_height = artwork.cell_size()
expected = (13 * cell_width) / (8 * cell_height)
assert fitted.width / fitted.height == pytest.approx(expected, rel=0.01)
assert (fitted.width, fitted.height) == (13 * cell_width, 8 * cell_height)
# the ink keeps its own 2:1 aspect instead of being cropped to the box
ink = ink_bbox(fitted)
assert ink is not None
left, top, right, bottom = ink
assert (right - left) / (bottom - top) == pytest.approx(2.0, rel=0.02)
# a wide image is padded above and below, and spans the full width
assert left == 0 and right == fitted.width
assert top > 0 and bottom < fitted.height
def test_an_image_with_alpha_gets_a_black_backing() -> None:
"""Transparent artwork is drawn over the mosaic; black keeps it readable."""
fitted = artwork.fit_image(png_bytes((400, 200)), 13, 8)
assert fitted is not None
# every pixel is opaque now, and the padding is black rather than mosaic
assert fitted.getchannel("A").getextrema() == (255, 255)
assert fitted.getpixel((0, 0)) == (0, 0, 0, 255)
# the ink is still letterboxed, not cropped: its own 2:1 aspect survives
ink = ink_bbox(fitted)
assert ink is not None
left, top, right, bottom = ink
assert (right - left) / (bottom - top) == pytest.approx(2.0, rel=0.02)
def test_an_opaque_image_keeps_the_transparent_padding() -> None:
"""No alpha channel: nothing to hide, so the mosaic shows through."""
fitted = artwork.fit_image(opaque_png_bytes((400, 200)), 13, 8)
assert fitted is not None
assert fitted.getpixel((0, 0))[3] == 0
ink = ink_bbox(fitted)
assert ink is not None
left, top, right, bottom = ink
assert (right - left) / (bottom - top) == pytest.approx(2.0, rel=0.02)
def test_fit_image_centres_a_tall_image() -> None:
fitted = artwork.fit_image(png_bytes((100, 400)), 13, 8)
assert fitted is not None
ink = ink_bbox(fitted)
assert ink is not None
left, _, right, _ = ink
assert left > 0 and right < fitted.width
assert right - left == pytest.approx(fitted.height / 4, rel=0.05)
def test_fit_image_rejects_garbage() -> None:
assert artwork.fit_image(b"not an image", 13, 8) is None