Alibrown commited on
Commit
57bd923
·
verified ·
1 Parent(s): 8ff240b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -35
app.py CHANGED
@@ -1,15 +1,16 @@
1
- # app.py - Streamlit für Hugging Face Spaces
2
  import os
3
  import tempfile
4
  import streamlit as st
5
  from PIL import Image
6
  import io
7
- import numpy as np # Immer noch nützlich, falls wir mal Arrays brauchen
 
 
 
8
 
9
  # ----------------------------------------------------
10
  # 🚨 KRITISCHE FIXES FÜR DEN PERMISSION ERROR (beibehalten)
11
- # Zwingt Streamlit, seine temporären/Konfigurationsdateien
12
- # in den beschreibbaren /tmp-Bereich zu schreiben.
13
  # ----------------------------------------------------
14
  TEMP_STREAMLIT_HOME = os.path.join(tempfile.gettempdir(), "st_config_workaround")
15
  os.makedirs(TEMP_STREAMLIT_HOME, exist_ok=True)
@@ -28,11 +29,29 @@ enableCORS = false
28
  with open(CONFIG_PATH, "w") as f:
29
  f.write(CONFIG_CONTENT)
30
 
31
- # --- Bildverarbeitungsfunktionen ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
  def stack_horizontal(img1, img2):
34
- """Stapelt zwei Bilder horizontal nebeneinander."""
35
- # Wandelt in RGB um, um die Transparenz in diesem Modus zu ignorieren
36
  img1 = img1.convert("RGB")
37
  img2 = img2.convert("RGB")
38
 
@@ -51,8 +70,7 @@ def stack_horizontal(img1, img2):
51
  return stacked_img
52
 
53
  def blend_images_cpu(img1, img2, alpha):
54
- """Blendet zwei Bilder mit Alpha-Faktor."""
55
- # Konvertiert in RGBA, um Transparenz beim Blenden zu unterstützen
56
  img1 = img1.convert("RGBA")
57
  img2 = img2.convert("RGBA")
58
 
@@ -60,43 +78,29 @@ def blend_images_cpu(img1, img2, alpha):
60
  img2 = img2.resize(img1.size, Image.Resampling.LANCZOS)
61
 
62
  blended = Image.blend(img1, img2, alpha)
63
- return blended.convert("RGB") # Rückgabe als RGB für Konsistenz im UI, wenn nicht transparent sein muss
64
 
65
  def overlay_image(background_img, overlay_img, x_pos, y_pos, scale_factor):
66
- """
67
- Überlagert ein freigestelltes Bild (overlay_img, muss RGBA sein)
68
- auf ein Hintergrundbild (background_img).
69
- Position und Skalierung sind einstellbar.
70
- """
71
- # Hintergrundbild immer als RGBA behandeln, um Alpha-Kanal zu ermöglichen
72
  background = background_img.convert("RGBA")
73
-
74
- # Overlay-Bild muss RGBA haben, um Transparenz zu unterstützen
75
  overlay = overlay_img.convert("RGBA")
76
 
77
- # Skalierung anwenden
78
  new_width = int(overlay.width * scale_factor)
79
  new_height = int(overlay.height * scale_factor)
80
  overlay = overlay.resize((new_width, new_height), Image.Resampling.LANCZOS)
81
 
82
- # Erstelle ein leeres Bild mit der Größe des Hintergrundbildes im RGBA-Modus
83
- # und paste das Hintergrundbild hinein
84
  result = Image.new("RGBA", background.size)
85
- result.paste(background, (0, 0)) # Füge das Hintergrundbild ein
 
86
 
87
- # Überlagere das zweite Bild (Katze) an der gewünschten Position
88
- # Die paste-Methode von Pillow verwendet den Alpha-Kanal des "mask"-Arguments,
89
- # wenn das überlagernde Bild einen Alpha-Kanal hat und als Maske übergeben wird.
90
- result.paste(overlay, (x_pos, y_pos), overlay) # 'overlay' als Maske verwenden
91
-
92
- return result.convert("RGB") # Rückgabe als RGB für die Anzeige
93
 
94
 
95
  # --- Streamlit UI ---
96
  st.set_page_config(page_title="Image Transformer", layout="wide")
97
 
98
- st.title("🖼️ CPU Image Transformer (Blend, Stack, Overlay)")
99
- st.markdown("**Blend** (überblenden), **Stack** (aneinanderreihen) oder **Overlay** (Katze auf Toilette 😎) - Reine CPU-Operation")
100
 
101
  col1, col2 = st.columns(2)
102
 
@@ -112,10 +116,22 @@ with col1:
112
 
113
  # Overlay-Parameter (nur bei Overlay relevant)
114
  with st.expander("Overlay-Optionen", expanded=(method == "Overlay (Position & Scale)")):
 
 
 
 
 
 
 
 
 
 
115
  x_pos = st.slider("X-Position des Overlays", 0, 1000, 0, 10, disabled=(method != "Overlay (Position & Scale)"))
116
  y_pos = st.slider("Y-Position des Overlays", 0, 1000, 0, 10, disabled=(method != "Overlay (Position & Scale)"))
117
  scale_factor = st.slider("Skalierung des Overlays", 0.1, 3.0, 1.0, 0.1, disabled=(method != "Overlay (Position & Scale)"))
118
- st.info("Für 'Overlay' sollte Bild 2 ein freigestelltes PNG mit Transparenz sein!")
 
 
119
 
120
  process_btn = st.button("🚀 Verarbeiten", type="primary")
121
 
@@ -137,15 +153,22 @@ if process_btn:
137
  elif method == "Stack Horizontal":
138
  result = stack_horizontal(img1, img2)
139
  elif method == "Overlay (Position & Scale)":
140
- # Hier ist es wichtig, dass img2 (Katze) einen Alpha-Kanal hat
141
- result = overlay_image(img1, img2, x_pos, y_pos, scale_factor)
 
 
 
 
 
 
 
142
 
143
  if result:
144
  result_placeholder.image(result, use_container_width=True)
145
 
146
  # Download-Button
147
  buf = io.BytesIO()
148
- result.save(buf, format="PNG") # PNG für Transparenz bei Overlay
149
  st.download_button(
150
  label="💾 Download Resultat",
151
  data=buf.getvalue(),
@@ -153,6 +176,9 @@ if process_btn:
153
  mime="image/png"
154
  )
155
  except Exception as e:
156
- st.error(f"Fehler: {e}")
 
 
 
157
  else:
158
  st.warning("⚠️ Bitte beide Bilder hochladen!")
 
1
+ # app.py - Streamlit für Hugging Face Spaces (MIT REMBG-INTEGRATION)
2
  import os
3
  import tempfile
4
  import streamlit as st
5
  from PIL import Image
6
  import io
7
+ import numpy as np
8
+
9
+ # NEUER IMPORT für die KI-gestützte Hintergrundentfernung
10
+ from rembg import remove
11
 
12
  # ----------------------------------------------------
13
  # 🚨 KRITISCHE FIXES FÜR DEN PERMISSION ERROR (beibehalten)
 
 
14
  # ----------------------------------------------------
15
  TEMP_STREAMLIT_HOME = os.path.join(tempfile.gettempdir(), "st_config_workaround")
16
  os.makedirs(TEMP_STREAMLIT_HOME, exist_ok=True)
 
29
  with open(CONFIG_PATH, "w") as f:
30
  f.write(CONFIG_CONTENT)
31
 
32
+ # --- NEUE FUNKTION: Hintergrundentfernung mit KI ---
33
+
34
+ def remove_background(image_pil):
35
+ """
36
+ Entfernt den Hintergrund eines Bildes mithilfe der rembg-Bibliothek.
37
+ Das Ergebnis ist ein PIL-Image mit Alpha-Kanal (RGBA).
38
+ """
39
+ # Konvertiere PIL Image zu Bytes für rembg (empfohlene Methode)
40
+ img_byte_arr = io.BytesIO()
41
+ image_pil.save(img_byte_arr, format='PNG')
42
+ input_bytes = img_byte_arr.getvalue()
43
+
44
+ # KI-Operation: Hintergrund entfernen
45
+ # Da wir auf CPU laufen, kann dies einige Sekunden dauern!
46
+ output_bytes = remove(input_bytes, alpha_matting=True)
47
+
48
+ # Konvertiere die Ergebnis-Bytes zurück zu einem PIL Image
49
+ return Image.open(io.BytesIO(output_bytes))
50
+
51
+ # --- Bildverarbeitungsfunktionen (Unverändert) ---
52
 
53
  def stack_horizontal(img1, img2):
54
+ # ... (Code unverändert) ...
 
55
  img1 = img1.convert("RGB")
56
  img2 = img2.convert("RGB")
57
 
 
70
  return stacked_img
71
 
72
  def blend_images_cpu(img1, img2, alpha):
73
+ # ... (Code unverändert) ...
 
74
  img1 = img1.convert("RGBA")
75
  img2 = img2.convert("RGBA")
76
 
 
78
  img2 = img2.resize(img1.size, Image.Resampling.LANCZOS)
79
 
80
  blended = Image.blend(img1, img2, alpha)
81
+ return blended.convert("RGB")
82
 
83
  def overlay_image(background_img, overlay_img, x_pos, y_pos, scale_factor):
84
+ # ... (Code unverändert) ...
 
 
 
 
 
85
  background = background_img.convert("RGBA")
 
 
86
  overlay = overlay_img.convert("RGBA")
87
 
 
88
  new_width = int(overlay.width * scale_factor)
89
  new_height = int(overlay.height * scale_factor)
90
  overlay = overlay.resize((new_width, new_height), Image.Resampling.LANCZOS)
91
 
 
 
92
  result = Image.new("RGBA", background.size)
93
+ result.paste(background, (0, 0))
94
+ result.paste(overlay, (x_pos, y_pos), overlay)
95
 
96
+ return result.convert("RGB")
 
 
 
 
 
97
 
98
 
99
  # --- Streamlit UI ---
100
  st.set_page_config(page_title="Image Transformer", layout="wide")
101
 
102
+ st.title("🖼️ CPU Image Transformer (Blend, Stack, KI-Overlay)")
103
+ st.markdown("**Blend** (überblenden), **Stack** (aneinanderreihen) oder **KI-Overlay** (Katze auf Klo!) - Reine CPU-Operation.")
104
 
105
  col1, col2 = st.columns(2)
106
 
 
116
 
117
  # Overlay-Parameter (nur bei Overlay relevant)
118
  with st.expander("Overlay-Optionen", expanded=(method == "Overlay (Position & Scale)")):
119
+
120
+ # NEUES UI-ELEMENT: KI-Freistellung
121
+ auto_remove_bg = st.checkbox(
122
+ "Automatisch freistellen (KI)",
123
+ value=False,
124
+ disabled=(method != "Overlay (Position & Scale)"),
125
+ help="Nutzt ein KI-Modell, um den Hintergrund von Bild 2 zu entfernen. **Achtung: Dies ist eine CPU-intensive Operation und kann die Verarbeitungszeit erhöhen.**"
126
+ )
127
+ st.divider() # Trennlinie
128
+
129
  x_pos = st.slider("X-Position des Overlays", 0, 1000, 0, 10, disabled=(method != "Overlay (Position & Scale)"))
130
  y_pos = st.slider("Y-Position des Overlays", 0, 1000, 0, 10, disabled=(method != "Overlay (Position & Scale)"))
131
  scale_factor = st.slider("Skalierung des Overlays", 0.1, 3.0, 1.0, 0.1, disabled=(method != "Overlay (Position & Scale)"))
132
+
133
+ if not auto_remove_bg:
134
+ st.info("Wenn **nicht** freigestellt wird, muss Bild 2 bereits ein **transparentes PNG** sein!")
135
 
136
  process_btn = st.button("🚀 Verarbeiten", type="primary")
137
 
 
153
  elif method == "Stack Horizontal":
154
  result = stack_horizontal(img1, img2)
155
  elif method == "Overlay (Position & Scale)":
156
+
157
+ # KI-Freistellungslogik HIER
158
+ overlay_img_final = img2
159
+ if auto_remove_bg:
160
+ st.text("KI: Hintergrund von Bild 2 wird entfernt...")
161
+ overlay_img_final = remove_background(img2)
162
+ st.text("KI: Freistellung abgeschlossen.")
163
+
164
+ result = overlay_image(img1, overlay_img_final, x_pos, y_pos, scale_factor)
165
 
166
  if result:
167
  result_placeholder.image(result, use_container_width=True)
168
 
169
  # Download-Button
170
  buf = io.BytesIO()
171
+ result.save(buf, format="PNG") # PNG ist wichtig, da es den Alpha-Kanal für den Download beibehält
172
  st.download_button(
173
  label="💾 Download Resultat",
174
  data=buf.getvalue(),
 
176
  mime="image/png"
177
  )
178
  except Exception as e:
179
+ st.error(f"Fehler bei der Verarbeitung: {e}")
180
+ # Füge hier weitere Debug-Informationen hinzu, wenn das Modell nicht lädt
181
+ if "No such file or directory" in str(e):
182
+ st.error("WICHTIG: Die KI-Modell-Dateien wurden nicht gefunden. Stelle sicher, dass `rembg` alle Abhängigkeiten korrekt geladen hat.")
183
  else:
184
  st.warning("⚠️ Bitte beide Bilder hochladen!")