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

+22 -6
View File
@@ -230,22 +230,38 @@ async def fetch(client: httpx.AsyncClient, url: str) -> bytes | None:
def fit_image(data: bytes, width: int, height: int):
"""Decode and center-crop an image to exactly ``width`` x ``height`` cells."""
"""Decode and letterbox an image into exactly ``width`` x ``height`` cells.
Scale to fit, never crop. Square album art fills the box either way, but a
wide station wordmark (Bassdrive's logo is 3:1) used to be centre-cropped
down to a zoomed slice of its middle. The padding stays transparent, so
the mosaic behind the artwork shows through instead of a black bar.
"""
try:
from PIL import Image, ImageOps
with Image.open(BytesIO(data)) as source:
# A PNG with transparency is drawn *over* the mosaic, which reads
# as noise behind a logo; composite those onto black instead.
has_alpha = source.mode in ("RGBA", "LA", "PA", "RGBa", "La") or (
"transparency" in source.info
)
image = source.convert("RGBA")
cell_width, cell_height = cell_size()
target = (
max(1, width * cell_width),
max(1, height * cell_height),
)
return ImageOps.fit(
image,
target,
method=Image.Resampling.LANCZOS,
centering=(0.5, 0.5),
fitted = ImageOps.contain(image, target, method=Image.Resampling.LANCZOS)
background = (0, 0, 0, 255) if has_alpha else (0, 0, 0, 0)
canvas = Image.new("RGBA", target, background)
canvas.alpha_composite(
fitted,
(
(target[0] - fitted.width) // 2,
(target[1] - fitted.height) // 2,
),
)
return canvas
except Exception:
return None