diff --git a/api/advent22_api/routers/days.py b/api/advent22_api/routers/days.py index 59fb293..af5cd36 100644 --- a/api/advent22_api/routers/days.py +++ b/api/advent22_api/routers/days.py @@ -76,6 +76,38 @@ async def load_picture_standard() -> Image.Image: return img.convert("RGB") +async def get_text_box( + img: Image.Image, + xy: tuple[float, float], + text: str | bytes, + font: "ImageFont._Font", + anchor: str | None = "mm", + **text_kwargs, +) -> tuple[int, int, int, int] | None: + mask = Image.new(mode="1", size=img.size, color=0) + + ImageDraw.Draw(mask).text( + xy=xy, + text=text, + font=font, + anchor=anchor, + fill=1, + **text_kwargs, + ) + + return mask.getbbox() + + +async def get_average_color( + img: Image.Image, + box: tuple[int, int, int, int], +) -> tuple[int, int, int]: + pixel_data = img.crop(box).getdata() + mean_color: np.ndarray = np.mean(pixel_data, axis=0) + + return tuple(mean_color.astype(int).tolist()) + + @router.get( "/picture/{index}", response_class=StreamingResponse, @@ -85,29 +117,28 @@ async def get_picture_for_day( img: Image.Image = Depends(load_picture_standard), ) -> StreamingResponse: font = ImageFont.truetype("Lena.ttf", 50) + xy = (200, 150) - txt_layer = Image.new(mode="RGB", size=(400, 400), color=(0, 0, 0)) - txt_color = (255, 255, 255) - - ImageDraw.Draw(txt_layer).text( - xy=(300, 300), + text_box = await get_text_box( + img=img, + xy=xy, text=letter, font=font, - anchor="mm", - fill=txt_color, ) - if (bbox := txt_layer.getbbox()) is not None: - mean = np.mean(img.crop(bbox).getdata(), axis=0) - txt_color = tuple(int(val) for val in mean) + if text_box is not None: + text_color = await get_average_color( + img=img, + box=text_box, + ) - ImageDraw.Draw(img).text( - xy=(300, 300), - text=letter, - font=font, - anchor="mm", - fill=txt_color, - ) + ImageDraw.Draw(img).text( + xy=xy, + text=letter, + font=font, + anchor="mm", + fill=text_color, + ) img_buffer = BytesIO() img.save(img_buffer, format="PNG", quality=85)