Image-Methoden nach _misc

This commit is contained in:
Jörn-Michael Miehe 2022-11-15 22:58:04 +00:00
parent fb9cfc0390
commit 2802b04657
2 changed files with 97 additions and 66 deletions

View file

@ -1,8 +1,18 @@
import itertools import itertools
import random import random
import re
from typing import Any, Sequence from typing import Any, Sequence
from ..config import get_config from fastapi import Depends
from PIL import ImageFont
from ..config import Config, get_config
from ..dav_common import dav_file_exists, dav_get_file, dav_list_files
from ._image import AdventImage
##########
# RANDOM #
##########
async def get_rnd(bonus_salt: Any = "") -> random.Random: async def get_rnd(bonus_salt: Any = "") -> random.Random:
@ -24,3 +34,86 @@ async def shuffle(seq: Sequence, rnd: random.Random | None = None) -> list:
# Elemente mischen # Elemente mischen
return rnd.sample(seq, len(seq)) return rnd.sample(seq, len(seq))
#########
# IMAGE #
#########
async def get_letter(
index: int,
cfg: Config = Depends(get_config),
) -> str:
return (await shuffle(cfg.solution))[index]
_RE_IMAGE_FILE = re.compile(
r"\.(gif|jpe?g|tiff?|png|bmp)$",
flags=re.IGNORECASE,
)
async def list_images_auto() -> list[str]:
"""
Finde alle Bilder im "automatisch"-Verzeichnis
"""
ls = await dav_list_files(_RE_IMAGE_FILE, "/images_auto")
ls = await set_length(ls, 24)
return await shuffle(ls)
async def load_image(
file_name: str,
) -> AdventImage:
"""
Versuche, Bild aus Datei zu laden
"""
if not await dav_file_exists(file_name):
raise RuntimeError(f"DAV-File {file_name} does not exist!")
img_buffer = await dav_get_file(file_name)
img_buffer.seek(0)
return await AdventImage.load_standard(img_buffer)
async def get_auto_image(
index: int,
letter: str = Depends(get_letter),
images: list[str] = Depends(list_images_auto),
) -> AdventImage:
"""
Erstelle automatisch generiertes Bild
"""
# hier niemals RuntimeError!
image = await load_image(images[index])
rnd = await get_rnd(index)
# Buchstabe verstecken
await image.hide_text(
xy=tuple(rnd.choices(range(30, 470), k=2)),
text=letter,
font=ImageFont.truetype("Lena.ttf", 50),
)
return image
async def get_image(
index: int,
letter: str = Depends(get_letter),
images: list[str] = Depends(list_images_auto),
) -> AdventImage:
"""
Bild für einen Tag erstellen
"""
try:
# Versuche, aus "manual"-Ordner zu laden
return await load_image(f"images_manual/{index}.jpg")
except RuntimeError:
# Erstelle automatisch generiertes Bild
return await get_auto_image(index=index, letter=letter, images=images)

View file

@ -1,15 +1,12 @@
import re
# from datetime import date # from datetime import date
from io import BytesIO from io import BytesIO
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from fastapi.responses import StreamingResponse from fastapi.responses import StreamingResponse
from PIL import ImageFont
from ..config import Config, get_config from ..config import Config, get_config
from ..dav_common import dav_file_exists, dav_get_file, dav_list_files
from ._image import AdventImage from ._image import AdventImage
from ._misc import get_rnd, set_length, shuffle from ._misc import get_image, shuffle
router = APIRouter(prefix="/days", tags=["days"]) router = APIRouter(prefix="/days", tags=["days"])
@ -54,77 +51,18 @@ async def get_letter(
# media_type="image/png", # media_type="image/png",
# ) # )
_RE_IMAGE_FILE = re.compile(
r"\.(gif|jpe?g|tiff?|png|bmp)$",
flags=re.IGNORECASE,
)
async def list_images_auto() -> list[str]:
ls = await dav_list_files(_RE_IMAGE_FILE, "/images_auto")
ls = await set_length(ls, 24)
return await shuffle(ls)
async def load_image(
file_name: str,
) -> AdventImage | None:
"""
Versuche, Bild aus Datei zu laden
"""
if not await dav_file_exists(file_name):
return None
img_buffer = await dav_get_file(file_name)
img_buffer.seek(0)
return await AdventImage.load_standard(img_buffer)
async def get_auto_image(
index: int,
letter: str = Depends(get_letter),
images: list[str] = Depends(list_images_auto),
) -> AdventImage:
image = await load_image(images[index])
assert image is not None
rnd = await get_rnd(index)
# Buchstabe verstecken
await image.hide_text(
xy=tuple(rnd.choices(range(30, 470), k=2)),
text=letter,
font=ImageFont.truetype("Lena.ttf", 50),
)
return image
@router.get( @router.get(
"/picture/{index}", "/picture/{index}",
response_class=StreamingResponse, response_class=StreamingResponse,
) )
async def get_picture_for_day( async def get_image_for_day(
index: int, image: AdventImage = Depends(get_image),
) -> StreamingResponse: ) -> StreamingResponse:
""" """
Bild für einen Tag erstellen Bild für einen Tag erstellen
""" """
# Versuche, aus "manual"-Ordner zu laden
image = await load_image(f"images_manual/{index}.jpg")
if image is None:
# Erstelle automatisch generiertes Bild
image = await get_auto_image(
index=index,
letter=await get_letter(index, await get_config()),
images=await list_images_auto()
)
# Bilddaten in Puffer laden # Bilddaten in Puffer laden
img_buffer = BytesIO() img_buffer = BytesIO()
image.img.save(img_buffer, format="JPEG", quality=85) image.img.save(img_buffer, format="JPEG", quality=85)