HEIC annehmen, und "Vogel ohne Art" nicht als "kein Vogel" melden

ZWEI FEHLER, BEIDE HEUTE ENTSTANDEN, BEIDE BEIM BENUTZEN GEFUNDEN.

1. 🔴 HEIC. Minuten nach dem Ausrollen der Bildpruefung wies die Instanz
   jedes Foto von Christians iPhone mit 400 ab. Die Pruefung war richtig --
   sie kannte nur das Format nicht, das die Haelfte aller Telefone erzeugt.
   Eine App fuer iOS, die kein HEIC annimmt, nimmt nichts an.

   pillow-heif in requirements-web.txt, Opener registriert, AVIF gleich mit.
   Fehlt das Paket, sagt die Meldung das jetzt ausdruecklich -- sonst sucht
   man den Fehler beim Telefon, und er liegt an einem fehlenden Paket auf
   dem Server.

2. 🔴 "VOGEL JA, ART NEIN" KAM ALS "KEIN VOGEL" AN. Pipeline.run gibt in
   drei Faellen kein Ergebnis zurueck: nichts gefunden, Beinahe-Treffer, und
   -- der interessante -- ein sicher erkannter Vogel, dessen Art keine
   heimische ist. Die Box unterscheidet die Faelle; die Warteschlange hat sie
   weggeworfen und 0.0 gemeldet.

   Folge: Ein Foto mit einem Vogel, den der Detektor mit 93 % gefunden hatte,
   kam in der App als "Kein Vogel erkannt. Auf dem Foto war nichts zu finden"
   an. Christian hat daraufhin zugeschnitten, wieder und wieder -- gegen ein
   Problem, das nie der Zuschnitt war.

   🔑 EINE FALSCHE AUSKUNFT IST TEURER ALS GAR KEINE. Sie schickt jemanden
   mit voller Ueberzeugung in die falsche Richtung.

   Jetzt traegt mean_bird_score den Wert der Box, und frames_with_bird haengt
   am Vogel statt an der Art.

7 neue Tests. 235 Web + 131 Detector gruen.
This commit is contained in:
Artemis committed 2026-10-14 18:09:06 +00:00
1 parent dbec78aa7a
commit f7184d193c
6 files changed
+161 -6

No files matched your search

+23 -2
View File
@@ -28,6 +28,24 @@ import io
from django.core.files.uploadedfile import InMemoryUploadedFile, UploadedFile
from PIL import Image, ImageOps, UnidentifiedImageError
# 🔴 **Ohne das kann Pillow kein HEIC — und iPhones fotografieren HEIC.**
#
# Am 14.10.2026 wies die Instanz jedes Foto von Christians iPhone mit 400 ab,
# Minuten nachdem die Bildprüfung ausgerollt war. Die Prüfung war richtig, nur
# kannte sie das Format nicht, das die Hälfte aller Telefone erzeugt. Eine
# App für iOS, die kein HEIC annimmt, nimmt nichts an.
#
# ⚠️ Der Import darf das Hochladen nicht zum Absturz bringen, wenn das Paket
# in einer schlanken Umgebung fehlt — dann bleibt es bei JPEG und PNG, und die
# Meldung an den Nutzer sagt, welches Format es war.
try: # pragma: no cover - haengt an der Umgebung, nicht am Code
import pillow_heif
pillow_heif.register_heif_opener()
HEIC_LESBAR = True
except ImportError: # pragma: no cover
HEIC_LESBAR = False
# ⚠️ Pillow öffnet sehr große Bilder bereitwillig und belegt dabei Speicher in
# der Größenordnung Breite × Höhe × 4 Bytes. Ein Bild mit absurden Maßen in
# einer winzigen Datei ist der billigste Weg, einen Dienst umzuwerfen
@@ -40,7 +58,7 @@ MAX_KANTE = 2400
# Was wir annehmen. Bewusst eine kurze Liste bekannter Rasterformate — kein
# SVG (das ist ein Dokument mit Skripten, kein Bild) und kein animiertes GIF.
ERLAUBT = {"JPEG", "PNG", "WEBP", "HEIF", "HEIC", "MPO"}
ERLAUBT = {"JPEG", "PNG", "WEBP", "HEIF", "HEIC", "AVIF", "MPO"}
class KeinBild(Exception):
@@ -65,7 +83,10 @@ def saeubern(datei: UploadedFile, name: str | None = None) -> InMemoryUploadedFi
# unbrauchbar. Deshalb danach neu öffnen statt weiterzuarbeiten.
bild.verify()
except (UnidentifiedImageError, OSError, ValueError) as fehler:
raise KeinBild(f"keine lesbare Bilddatei: {fehler}") from fehler
# ⚠️ Den Hinweis auf HEIC mitgeben: Ohne ihn sucht man den Fehler beim
# Telefon, und er liegt an einem fehlenden Paket auf dem Server.
hinweis = "" if HEIC_LESBAR else " (HEIC wird hier nicht unterstützt — pillow-heif fehlt)"
raise KeinBild(f"keine lesbare Bilddatei{hinweis}: {fehler}") from fehler
datei.seek(0)
try: