Spaces:
Running
Running
File size: 7,379 Bytes
57bd923 914bd5e 57bd923 914bd5e 57bd923 914bd5e 57bd923 914bd5e 57bd923 914bd5e 57bd923 914bd5e 57bd923 914bd5e 57bd923 914bd5e 57bd923 914bd5e 57bd923 914bd5e 57bd923 914bd5e 57bd923 914bd5e 57bd923 914bd5e 57bd923 914bd5e 57bd923 914bd5e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# app.py - Streamlit für Hugging Face Spaces (MIT REMBG-INTEGRATION)
import os
import tempfile
import streamlit as st
from PIL import Image
import io
import numpy as np
# NEUER IMPORT für die KI-gestützte Hintergrundentfernung
from rembg import remove
# ----------------------------------------------------
# 🚨 KRITISCHE FIXES FÜR DEN PERMISSION ERROR (beibehalten)
# ----------------------------------------------------
TEMP_STREAMLIT_HOME = os.path.join(tempfile.gettempdir(), "st_config_workaround")
os.makedirs(TEMP_STREAMLIT_HOME, exist_ok=True)
os.environ["STREAMLIT_HOME"] = TEMP_STREAMLIT_HOME
os.environ["STREAMLIT_GATHER_USAGE_STATS"] = "false"
CONFIG_PATH = os.path.join(TEMP_STREAMLIT_HOME, "config.toml")
CONFIG_CONTENT = """
[browser]
gatherUsageStats = false
[server]
headless = true
port = 7860
enableCORS = false
"""
with open(CONFIG_PATH, "w") as f:
f.write(CONFIG_CONTENT)
# --- NEUE FUNKTION: Hintergrundentfernung mit KI ---
def remove_background(image_pil):
"""
Entfernt den Hintergrund eines Bildes mithilfe der rembg-Bibliothek.
Das Ergebnis ist ein PIL-Image mit Alpha-Kanal (RGBA).
"""
# Konvertiere PIL Image zu Bytes für rembg (empfohlene Methode)
img_byte_arr = io.BytesIO()
image_pil.save(img_byte_arr, format='PNG')
input_bytes = img_byte_arr.getvalue()
# KI-Operation: Hintergrund entfernen
# Da wir auf CPU laufen, kann dies einige Sekunden dauern!
output_bytes = remove(input_bytes, alpha_matting=True)
# Konvertiere die Ergebnis-Bytes zurück zu einem PIL Image
return Image.open(io.BytesIO(output_bytes))
# --- Bildverarbeitungsfunktionen (Unverändert) ---
def stack_horizontal(img1, img2):
# ... (Code unverändert) ...
img1 = img1.convert("RGB")
img2 = img2.convert("RGB")
h1, h2 = img1.size[1], img2.size[1]
if h1 != h2:
w2_new = int(img2.size[0] * h1 / h2)
img2 = img2.resize((w2_new, h1), Image.Resampling.LANCZOS)
total_width = img1.size[0] + img2.size[0]
total_height = img1.size[1]
stacked_img = Image.new('RGB', (total_width, total_height))
stacked_img.paste(img1, (0, 0))
stacked_img.paste(img2, (img1.size[0], 0))
return stacked_img
def blend_images_cpu(img1, img2, alpha):
# ... (Code unverändert) ...
img1 = img1.convert("RGBA")
img2 = img2.convert("RGBA")
if img1.size != img2.size:
img2 = img2.resize(img1.size, Image.Resampling.LANCZOS)
blended = Image.blend(img1, img2, alpha)
return blended.convert("RGB")
def overlay_image(background_img, overlay_img, x_pos, y_pos, scale_factor):
# ... (Code unverändert) ...
background = background_img.convert("RGBA")
overlay = overlay_img.convert("RGBA")
new_width = int(overlay.width * scale_factor)
new_height = int(overlay.height * scale_factor)
overlay = overlay.resize((new_width, new_height), Image.Resampling.LANCZOS)
result = Image.new("RGBA", background.size)
result.paste(background, (0, 0))
result.paste(overlay, (x_pos, y_pos), overlay)
return result.convert("RGB")
# --- Streamlit UI ---
st.set_page_config(page_title="Image Transformer", layout="wide")
st.title("🖼️ CPU Image Transformer (Blend, Stack, KI-Overlay)")
st.markdown("**Blend** (überblenden), **Stack** (aneinanderreihen) oder **KI-Overlay** (Katze auf Klo!) - Reine CPU-Operation.")
col1, col2 = st.columns(2)
with col1:
st.subheader("Eingabe & Steuerung")
img1_file = st.file_uploader("Bild 1 (Basisbild / Hintergrund)", type=["png", "jpg", "jpeg", "webp"])
img2_file = st.file_uploader("Bild 2 (Zusatzbild / Overlay)", type=["png", "jpg", "jpeg", "webp"])
method = st.selectbox("Transformationsmethode", ["Blend", "Stack Horizontal", "Overlay (Position & Scale)"])
# Blending-Faktor (nur bei Blend relevant)
alpha = st.slider("Blending-Faktor (Alpha, nur bei 'Blend' aktiv)", 0.0, 1.0, 0.5, 0.05, disabled=(method != "Blend"))
# Overlay-Parameter (nur bei Overlay relevant)
with st.expander("Overlay-Optionen", expanded=(method == "Overlay (Position & Scale)")):
# NEUES UI-ELEMENT: KI-Freistellung
auto_remove_bg = st.checkbox(
"Automatisch freistellen (KI)",
value=False,
disabled=(method != "Overlay (Position & Scale)"),
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.**"
)
st.divider() # Trennlinie
x_pos = st.slider("X-Position des Overlays", 0, 1000, 0, 10, disabled=(method != "Overlay (Position & Scale)"))
y_pos = st.slider("Y-Position des Overlays", 0, 1000, 0, 10, disabled=(method != "Overlay (Position & Scale)"))
scale_factor = st.slider("Skalierung des Overlays", 0.1, 3.0, 1.0, 0.1, disabled=(method != "Overlay (Position & Scale)"))
if not auto_remove_bg:
st.info("Wenn **nicht** freigestellt wird, muss Bild 2 bereits ein **transparentes PNG** sein!")
process_btn = st.button("🚀 Verarbeiten", type="primary")
with col2:
st.subheader("Resultat")
result_placeholder = st.empty()
# Verarbeitung
if process_btn:
if img1_file and img2_file:
with st.spinner("Verarbeite..."):
try:
img1 = Image.open(img1_file)
img2 = Image.open(img2_file)
result = None
if method == "Blend":
result = blend_images_cpu(img1, img2, alpha)
elif method == "Stack Horizontal":
result = stack_horizontal(img1, img2)
elif method == "Overlay (Position & Scale)":
# KI-Freistellungslogik HIER
overlay_img_final = img2
if auto_remove_bg:
st.text("KI: Hintergrund von Bild 2 wird entfernt...")
overlay_img_final = remove_background(img2)
st.text("KI: Freistellung abgeschlossen.")
result = overlay_image(img1, overlay_img_final, x_pos, y_pos, scale_factor)
if result:
result_placeholder.image(result, use_container_width=True)
# Download-Button
buf = io.BytesIO()
result.save(buf, format="PNG") # PNG ist wichtig, da es den Alpha-Kanal für den Download beibehält
st.download_button(
label="💾 Download Resultat",
data=buf.getvalue(),
file_name=f"result_{method.lower().replace(' ', '_')}.png",
mime="image/png"
)
except Exception as e:
st.error(f"Fehler bei der Verarbeitung: {e}")
# Füge hier weitere Debug-Informationen hinzu, wenn das Modell nicht lädt
if "No such file or directory" in str(e):
st.error("WICHTIG: Die KI-Modell-Dateien wurden nicht gefunden. Stelle sicher, dass `rembg` alle Abhängigkeiten korrekt geladen hat.")
else:
st.warning("⚠️ Bitte beide Bilder hochladen!") |