fix: Logo nicht komplett wegradieren, wenn es dem Hintergrund aehnelt

Ein helles Logo auf hellem Grund liegt innerhalb der Farbtoleranz des
Flood Fill. Der Fuellvorgang lief vom Rand in das Logo hinein und
loeschte es mit - das Ergebnis war ein vollstaendig transparentes PNG,
auf der Willkommensseite also gar kein Logo. Ohne jede Rueckmeldung:
die bisherige Pruefung schlug nur an, wenn *nichts* entfernt wurde, nicht
wenn alles entfernt wurde.

remove_logo_background() legt jetzt vor dem Eingriff eine Kopie an und
misst danach ueber das Alpha-Histogramm, wie viel sichtbar geblieben
ist. Unter 2% gilt der Versuch als misslungen: das unveraenderte Bild
wird zurueckgegeben und die Oberflaeche nennt den Grund samt Auswegen
(transparentes PNG hochladen oder "Hintergrund behalten" ankreuzen).

Getestet mit Logos von dunkelrot bis reinweiss auf weissem Grund sowie
einem dunklen Logo auf schwarzem Grund.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Erik Thiele
2026-09-02 15:27:06 +02:00
parent a3b9fe59b7
commit a25566aab4
4 changed files with 21 additions and 4 deletions

View File

@@ -112,6 +112,10 @@ def remove_logo_background(image, tolerance=LOGO_TOLERANCE):
return img, ("Der Bildrand ist nicht einfarbig – das Logo wurde unverändert "
"übernommen. Am besten ein PNG mit transparentem Hintergrund hochladen.")
# Vor dem Eingriff sichern: ist das Logo farblich zu nah am Hintergrund,
# frisst der Flood Fill es mit auf und wir muessen zurueckfallen koennen.
original = img.copy()
# Flood Fill von allen Randpixeln aus
besucht = bytearray(w * h)
queue = deque()
@@ -155,7 +159,20 @@ def remove_logo_background(image, tolerance=LOGO_TOLERANCE):
if d < tolerance * 2:
px[x, y] = (r, g, b, int(255 * max(0.0, (d - tolerance) / tolerance)))
if not any(px[x, y][3] == 0 for x in range(0, w, max(1, w // 50)) for y in (0, h - 1)):
# Wie viel ist uebrig geblieben? Ein helles Logo auf hellem Grund liegt
# innerhalb der Toleranz und wuerde komplett mit entfernt - das Ergebnis
# waere ein leeres Bild und auf der Willkommensseite gar kein Logo.
histogramm = img.getchannel("A").histogram()
sichtbar = sum(histogramm[1:])
anteil = sichtbar / float(w * h)
if anteil < 0.02:
return original, ("Das Logo ist farblich zu nah am Hintergrund – beim Freistellen "
"wäre fast nichts übrig geblieben. Es wurde deshalb unverändert "
"übernommen. Am besten ein PNG mit transparentem Hintergrund "
"hochladen oder die Option \u201eHintergrund behalten\u201c ankreuzen.")
if anteil > 0.999:
return img, "Es wurde kein zusammenhängender Hintergrund gefunden."
return img, None