import gradio as gr import numpy as np from PIL import Image, ImageDraw, ImageFont def overlay_plan(image, sockets, switches, room_type, price_socket, price_switch, cable_per_point_m, cable_price_per_m, customer_view): img = image.convert("RGBA") w, h = img.size draw = ImageDraw.Draw(img) # simple suggested positions (rule-based) # sockets along lower wall line; switches near "door" area left side socket_points = [] switch_points = [] # distribute sockets on bottom area for i in range(sockets): x = int((i + 1) * w / (sockets + 1)) y = int(h * 0.83) socket_points.append((x, y)) # switches on left side mid height for i in range(switches): x = int(w * 0.12) y = int(h * (0.45 + (i - (switches-1)/2) * 0.12)) switch_points.append((x, y)) # draw overlays def draw_marker(xy, label, color): r = max(10, int(min(w, h) * 0.015)) x, y = xy draw.ellipse((x-r, y-r, x+r, y+r), outline=color, width=4) draw.text((x+r+6, y-r-6), label, fill=color) for idx, p in enumerate(socket_points, start=1): draw_marker(p, f"SD{idx}", (0, 255, 0, 255)) # Steckdose for idx, p in enumerate(switch_points, start=1): draw_marker(p, f"SW{idx}", (255, 165, 0, 255)) # Schalter # rough cable estimate points_total = sockets + switches cable_m = points_total * max(0.0, float(cable_per_point_m)) # costs cost_sockets = sockets * float(price_socket) cost_switches = switches * float(price_switch) cost_cable = cable_m * float(cable_price_per_m) total = cost_sockets + cost_switches + cost_cable if customer_view: summary = ( f"Raumtyp: {room_type}\n" f"Vorschlag: {sockets} Steckdosen, {switches} Schalter\n" f"Geschätzte Leitung: {cable_m:.1f} m\n" f"(Kosten ausgeblendet – Kundenansicht)" ) else: summary = ( f"Raumtyp: {room_type}\n" f"Steckdosen: {sockets} x {price_socket:.2f} € = {cost_sockets:.2f} €\n" f"Schalter: {switches} x {price_switch:.2f} € = {cost_switches:.2f} €\n" f"Leitung: {cable_m:.1f} m x {cable_price_per_m:.2f} € = {cost_cable:.2f} €\n" f"-----------------------------\n" f"Summe (grob): {total:.2f} €" ) return img.convert("RGB"), summary with gr.Blocks(title="Smartelektric – Raum-Planer (Prototyp)") as demo: gr.Markdown("## Smartelektric – Raum-Planer (Prototyp)\nFoto hochladen → Vorschlag + Material/Kosten grob") with gr.Row(): inp = gr.Image(type="pil", label="Raumfoto (Rohbau / Bestand)") out = gr.Image(type="pil", label="Vorschau mit Markierungen") room_type = gr.Dropdown( ["Wohnzimmer", "Schlafzimmer", "Küche", "Bad", "Flur", "Büro", "Kinderzimmer", "Sonstiges"], value="Wohnzimmer", label="Raumtyp" ) with gr.Row(): sockets = gr.Slider(0, 20, value=6, step=1, label="Anzahl Steckdosen (Vorschlag)") switches = gr.Slider(0, 10, value=2, step=1, label="Anzahl Schalter (Vorschlag)") with gr.Row(): price_socket = gr.Number(value=50, label="Preis pro Steckdose (inkl. z.B. 5m Leitung) €") price_switch = gr.Number(value=25, label="Preis pro Schalter €") with gr.Row(): cable_per_point_m = gr.Number(value=5, label="Leitung pro Punkt (m) – grobe Annahme") cable_price_per_m = gr.Number(value=1.8, label="Leitungspreis pro Meter €") customer_view = gr.Checkbox(value=False, label="Kundenansicht (Kosten ausblenden)") summary = gr.Textbox(label="Auswertung", lines=10) btn = gr.Button("Generieren") btn.click( overlay_plan, inputs=[inp, sockets, switches, room_type, price_socket, price_switch, cable_per_point_m, cable_price_per_m, customer_view], outputs=[out, summary] ) demo.launch()