from PIL import Image, ImageDraw, ImageFont import gradio as gr import numpy as np import cv2 def add_text_to_image(image, text, text_x, text_y, font_size="80px", font_family="Standard", font_color="Weiß"): """Fügt Text mit OpenCV zum Bild hinzu - garantiert skalierbar!""" if image is None or not text: return image try: # Konvertiere PIL Image zu OpenCV Format if isinstance(image, np.ndarray): opencv_image = image else: opencv_image = np.array(image) opencv_image = cv2.cvtColor(opencv_image, cv2.COLOR_RGB2BGR) # Schriftgröße try: pixel_size = int(font_size.replace("px", "")) # OpenCV Font-Skala anpassen (empirische Werte) font_scale = pixel_size / 30.0 except: font_scale = 2.0 # Schriftfarbe color_mapping = { "Weiß": (255, 255, 255), "Schwarz": (0, 0, 0), "Rot": (0, 0, 255) } actual_color = color_mapping.get(font_color, (255, 255, 255)) # OpenCV Font basierend auf Auswahl font_mapping = { "Standard": cv2.FONT_HERSHEY_SIMPLEX, "Einfache Handschrift": cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, "Verschnörkelte Handschrift": cv2.FONT_HERSHEY_SCRIPT_COMPLEX } font = font_mapping.get(font_family, cv2.FONT_HERSHEY_SIMPLEX) thickness = max(2, int(pixel_size / 20)) print(f"OpenCV Text: '{text}' an ({text_x}, {text_y}) - Schrift: {font_family}, Größe: {font_scale:.2f}, Dicke: {thickness}") # Text mit OpenCV hinzufügen cv2.putText( opencv_image, text, (int(text_x), int(text_y)), font, font_scale, actual_color, thickness, cv2.LINE_AA ) # Zurück zu PIL Format result_image = cv2.cvtColor(opencv_image, cv2.COLOR_BGR2RGB) return Image.fromarray(result_image) except Exception as e: print(f"Fehler beim Text hinzufügen mit OpenCV: {e}") # Fallback zu PIL try: if isinstance(image, np.ndarray): image = Image.fromarray(image) image_with_text = image.copy() draw = ImageDraw.Draw(image_with_text) draw.text((text_x, text_y), text, fill="white") return image_with_text except: return image def create_text_preview(image, text, text_x, text_y, font_size="80px", font_family="Standard", font_color="Weiß"): """Vorschau mit OpenCV""" if image is None: return image try: # Zu OpenCV konvertieren if isinstance(image, np.ndarray): opencv_image = image else: opencv_image = np.array(image) opencv_image = cv2.cvtColor(opencv_image, cv2.COLOR_RGB2BGR) preview = opencv_image.copy() # Rote Marker if text and text_x is not None and text_y is not None and (text_x != 100 or text_y != 100): cv2.circle(preview, (int(text_x), int(text_y)), 8, (0, 0, 255), -1) # Text zeichnen if text: try: pixel_size = int(font_size.replace("px", "")) font_scale = pixel_size / 30.0 except: font_scale = 2.0 color_mapping = { "Weiß": (255, 255, 255), "Schwarz": (0, 0, 0), "Rot": (0, 0, 255) } actual_color = color_mapping.get(font_color, (255, 255, 255)) # OpenCV Font basierend auf Auswahl font_mapping = { "Standard": cv2.FONT_HERSHEY_SIMPLEX, "Einfache Handschrift": cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, "Verschnörkelte Handschrift": cv2.FONT_HERSHEY_SCRIPT_COMPLEX } font = font_mapping.get(font_family, cv2.FONT_HERSHEY_SIMPLEX) thickness = max(2, int(pixel_size / 20)) cv2.putText( preview, text, (int(text_x), int(text_y)), font, font_scale, actual_color, thickness, cv2.LINE_AA ) print(f"OpenCV Vorschau: Schrift {font_family}, Größe {font_scale:.2f}") # Zurück zu PIL result_image = cv2.cvtColor(preview, cv2.COLOR_BGR2RGB) return Image.fromarray(result_image) except Exception as e: print(f"Fehler bei OpenCV Vorschau: {e}") return image def update_text_preview_i2i(original_image, generated_image, text, text_x, text_y, font_size, font_family, font_color, target_selector): """Aktualisiert die Text-Vorschau für Bild-zu-Bild mit Formatierung""" if target_selector == "Originalbild": target_image = original_image else: target_image = generated_image print(f"Update Vorschau I2I - Größe: {font_size}, Schrift: {font_family}, Farbe: {font_color}, Ziel: {target_selector}") return create_text_preview(target_image, text, text_x, text_y, font_size, font_family, font_color) def update_text_preview_t2i(image, text, text_x, text_y, font_size, font_family, font_color): """Aktualisiert die Text-Vorschau für Text-zu-Bild mit Formatierung""" print(f"Update Vorschau T2I - Größe: {font_size}, Schrift: {font_family}, Farbe: {font_color}") return create_text_preview(image, text, text_x, text_y, font_size, font_family, font_color) def capture_click(event: gr.SelectData): """Handhabt Klicks in beiden Tabs""" if event and hasattr(event, 'index'): print(f"🎯 CLICK ERFOLGREICH: ({event.index[0]}, {event.index[1]})") return event.index[0], event.index[1] return 100, 100 def create_text_integration_section_t2i(): """Erstellt die UI-Komponenten für Text-Integration in Text-zu-Bild""" with gr.Row(): gr.Markdown("### 📝 Text auf Bild integrieren") with gr.Row(): text_input_t2i = gr.Textbox( label="Text eingeben", placeholder="Dein Text hier...", max_lines=2, scale=3 ) with gr.Row(): with gr.Column(): font_size_t2i = gr.Dropdown( choices=["120px", "80px", "40px"], value="80px", label="Schriftgröße" ) with gr.Column(): font_family_t2i = gr.Dropdown( choices=["Standard", "Einfache Handschrift", "Verschnörkelte Handschrift"], value="Standard", label="Schriftart" ) with gr.Column(): font_color_t2i = gr.Dropdown( choices=["Weiß", "Schwarz", "Rot"], value="Weiß", label="Schriftfarbe" ) with gr.Row(): text_x_t2i = gr.Number(value=None, visible=False) text_y_t2i = gr.Number(value=None, visible=False) with gr.Row(): text_btn_t2i = gr.Button("📝 Text auf generiertes Bild", variant="secondary") return text_input_t2i, text_x_t2i, text_y_t2i, font_size_t2i, font_family_t2i, font_color_t2i, text_btn_t2i def create_text_integration_section_i2i(): """Erstellt die UI-Komponenten für Text-Integration in Bild-zu-Bild""" with gr.Row(): gr.Markdown("### 📝 Text auf Bild integrieren") with gr.Row(): text_input_i2i = gr.Textbox( label="Text eingeben", placeholder="Dein Text hier...", max_lines=2, scale=3 ) with gr.Row(): text_x_i2i = gr.Number(value=None, visible=False) text_y_i2i = gr.Number(value=None, visible=False) with gr.Row(): target_selector = gr.Radio( choices=["Originalbild", "Generiertes Bild"], value="Generiertes Bild", label="Text auf welchem Bild?", scale=2 ) with gr.Row(): text_btn_i2i = gr.Button("📝 Text integrieren", variant="secondary") return text_input_i2i, text_x_i2i, text_y_i2i, target_selector, text_btn_i2i