Zuschnitt als Regel statt als gespeichertes Bild

Die Sichtung merkt sich jetzt, WO der Vogel im Foto sitzt (vier Zahlen); die
Anzeige schneidet daraus bei jedem Aufruf. Eine geaenderte Regel wirkt damit
sofort auf den ganzen Bestand. Altbestand faellt auf das alte Bild zurueck.
This commit is contained in:
Artemis committed 2026-10-14 18:28:50 +00:00
1 parent f572c20080
commit d8d3efaa5d
14 files changed
+421 -19

No files matched your search

+27
View File
@@ -76,6 +76,30 @@ def config(request: HttpRequest) -> JsonResponse:
return JsonResponse(kamera.konfiguration())
def _box_uebernehmen(sighting, payload) -> None:
"""Wo der Vogel im Bild sitzt, als vier relative Zahlen.
🔑 Damit ist der Zuschnitt eine Regel statt einer Datei: Die Anzeige
schneidet aus dem Original, und eine bessere Regel wirkt auf den ganzen
Bestand. Siehe ``dex/zuschnitt.py``.
⚠️ Nur vollständige und plausible Vierecke übernehmen. Ein halbes Viereck
ist keins, und eine vertauschte Kante ergäbe einen leeren Ausschnitt —
sichtbar würde das erst als graue Kachel, weit weg von hier.
"""
box = payload.get("box")
if not isinstance(box, (list, tuple)) or len(box) != 4:
return
try:
x0, y0, x1, y1 = (float(w) for w in box)
except (TypeError, ValueError):
return
if not (0.0 <= x0 < x1 <= 1.0 and 0.0 <= y0 < y1 <= 1.0):
return
sighting.box_x0, sighting.box_y0 = x0, y0
sighting.box_x1, sighting.box_y1 = x1, y1
def _parse_dt(value: str | None) -> datetime | None:
if not value:
return None
@@ -182,6 +206,8 @@ def ingest(request: HttpRequest) -> JsonResponse:
# Der Token EINER Kamera genügt, um Dateien unter der öffentlichen
# Medienadresse abzulegen — und ein kompromittierter Standort ist genau
# der Fall, für den die Token je Kamera getrennt sind. Siehe bilder.py.
_box_uebernehmen(sighting, payload)
try:
if "image" in request.FILES:
sighting.image = saeubern(request.FILES["image"])
@@ -567,6 +593,7 @@ def bestimmt_melden(request: HttpRequest, sichtung_id: int) -> JsonResponse:
# beruht: Artsicherheit 0 heißt „welche Art?", Vogelwert 0 heißt „gar kein
# Vogel". Siehe die Begründung bei ``ingest``.
sighting.frames_with_bird = 1 if (species or sighting.mean_bird_score > 0) else 0
_box_uebernehmen(sighting, payload)
sighting.wartet_auf_bestimmung = False
if "crop" in request.FILES:
sighting.crop = request.FILES["crop"]