import gradio as gr from gradio.themes.utils.colors import Color import random, time, shared, argparse, modules.path, fooocus_version, modules.html import modules.async_worker as worker from math import floor from PIL import Image, ImageDraw, ImageFont from modules.sdxl_styles import style_keys, aspect_ratios QM_LOGO=Image.open("resources/qm_logo.png") QM_COLOR=Color(name="qm", c50="#effaed",c100="#def5db",c200="#64b445",c300="#c6eec0",c400="#b9ebb3",c500="#64b445",c600="#55993b",c700="#467e30",c800="#325a23",c900="#233f18",c950="#192d11") def generate(*args): yield gr.update(interactive=False), \ gr.update(visible=True, value=modules.html.make_progress_html(1, "0/30")), \ gr.update(visible=True), \ gr.update(visible=False) while worker.is_working: time.sleep(0.1) worker.buffer=[list(args)] worker.outputs = [] finished=False while not finished: time.sleep(0.01) if len(worker.outputs) > 0: flag, product = worker.outputs.pop(0) if flag == 'preview': percentage, title, image = product yield gr.update(), \ gr.update(value=modules.html.make_progress_html(percentage, title)), \ gr.update(value=image) if image is not None else gr.update(), \ gr.update() if flag == 'results': image = product[0] yield gr.update(interactive=True), \ gr.update(visible=False), \ gr.update(visible=False, value=image), \ gr.update(visible=True) finished = True return def toggle_greet_visibility(is_visible): return gr.update(visible=is_visible), gr.update(visible=is_visible) def debounce(): time.sleep(0.5) return gr.update() def pil_image_with_overlay(pil_image, toggle_greet, greet): image = ImageDraw.Draw(pil_image, "RGBA") HEIGHT, TEXT_PADDING, TEXTBOX_HEIGHT = 100, 32, 56 TEXTBOX_WIDTH = 1280-HEIGHT-4*TEXT_PADDING image.rectangle(((0 if toggle_greet else 1280-HEIGHT-2*TEXT_PADDING, 768-HEIGHT), (1280, 768)), fill=(255, 255, 255, 222)) image._image.paste(QM_LOGO, (1135,675), QM_LOGO) if (toggle_greet): txt_image = Image.new('RGBA', (4*1280, 4*TEXTBOX_HEIGHT), (255,255,255,0)) ImageDraw.Draw(txt_image).text(xy=(0,0), text=greet, font=ImageFont.truetype('resources/SourceSansPro-Regular.ttf', floor(1.5*TEXTBOX_HEIGHT)), fill=(100, 180, 69)) image_box = txt_image.getbbox() txt_image = txt_image.crop(image_box) width, height = txt_image.size if (height > 0 and width/height < TEXTBOX_WIDTH/TEXTBOX_HEIGHT): txt_image = txt_image.resize((floor((TEXTBOX_HEIGHT/height)*width), TEXTBOX_HEIGHT)) else: txt_image = txt_image.resize((TEXTBOX_WIDTH, floor((TEXTBOX_WIDTH/width)*height))) _, height = txt_image.size image._image.paste(txt_image, (TEXT_PADDING, 768 - floor((HEIGHT+height)/2)), txt_image) return image._image def make_overlay(image, toggle_greet, greet): return gr.update(value=pil_image_with_overlay(image, toggle_greet, greet)) shared.gradio_root = gr.Blocks(title='QualityMinds AI Christmas Card Maker', css=modules.html.css, theme=gr.themes.Default(primary_hue=QM_COLOR)) with shared.gradio_root: gr.Markdown( """ # QualityMinds KI Weihnachtskarten-Generator * Beschreibe das Motiv der Weihnachtskarte in einem Prompt (Englisch), wähle ggf. Stil und los! * Zur Übersetzung einer Beschreibung ins Englische eignet sich beispielsweise [deepl.com](https://www.deepl.com/translator#de/Schneekugeln) helfen. * Chat-KIs wie [Bing Chat](https://www.bing.com/search?q=Bing+AI&showconv=1) können bei der Erstellung persönlicher Weihnachtsgrüße helfen, z.B. mit Prompts wie * Erstelle fünf unterschiedliche persönliche Weihnachtsgrüße für meinen Vater Anakin (je ca. 120 Zeichen). Erwähne dabei unseren gemeinsamen Urlaub auf Tatooine. * Erstelle drei unterschiedliche persönliche Weihnachtsgrüße für meinen geschätzten Arbeitskollegen Michael (je ca. 150 Zeichen). Gehe dabei Schritt für Schritt vor. * Erstelle fünf unterschiedliche persönliche Weihnachtsgrüße für eine Weihnachtskarte, auf der eine Schneekugel abgebildet ist (je ca. 133 Zeichen) und erkläre diese. * Dieses Werkzeug basiert auf [Stable Diffusion XL](https://stability.ai/stable-diffusion) v1.0 und der Oberfläche [Fooocus](https://github.com/lllyasviel/Fooocus), der Code ist OpenSource auf [Github](https://github.com/QualityMinds/AI-Christmas-Cards) verfügbar. """) with gr.Row(elem_classes='type_row'): with gr.Column(scale=2): gr.Markdown("##### Prompt (Englisch)", elem_classes="input-label") prompt = gr.Textbox(label="Prompt (Englisch)", value="", placeholder="Was möchtest Du auf der Weihnachtskarte abbilden?", autofocus=True, elem_classes='type_row', container=False, lines=2) description_de = gr.Textbox(label="Beschreibung", visible=False) gr.Markdown("##### Beispiele", elem_classes="input-label") gr.Examples(examples=[["Der Weihnachtsmann mit seinem Sack voller Geschenke", "Santa Claus with his sack full of gifts"], ["Malerisches Winterdorf in einer Schneekugel", "Scenic winter village inside a snow globe"], ["Niedliche Pinguine in Schals und Mützen eingewickelt", "Cute penguins wrapped up in scarves and hats"]], inputs=[description_de, prompt], elem_id="prompt-examples", cache_examples=False) with gr.Column(scale=1, min_width="120px"): gr.Markdown("##### Stil", elem_classes="input-label") style_selection = gr.Dropdown(choices=style_keys, value='Kinofilm', container=False) run_button = gr.Button(value="Weihnachtskarte\nerstellen", variant='primary', elem_classes='generate_button') progress_html = gr.HTML(visible=False, elem_id='progress-bar', elem_classes='progress-bar') with gr.Row(elem_classes='type_row'): example_texts = [ "Ich wünsche dir von Herzen ein frohes Weihnachtsfest.", "Frohe Weihnachten und viele glückliche Momente mit deinen Liebsten!", "Zauberhafte Weihnachten für dich!!", "Möge die Magie von Weihnachten dein Herz erleuchten und deine Wünsche erfüllen." ] with gr.Column(scale=1): toggle_greet = gr.Checkbox(label="Persönliche Weihnachtsgrüße hinzufügen", elem_id="toggle-greet-checkbox", container=False, value=True, interactive=True) greet = gr.Textbox(value=example_texts[0], placeholder="", interactive=True, elem_classes='type_row', container=False, lines=2, max_lines=2) greet_examples_column = gr.Column(scale=2) with greet_examples_column: gr.Markdown("##### Beispiele", elem_classes="input-label") greet_examples = gr.Examples(label="Beispiele", examples=example_texts, inputs=[greet], elem_id="greet-examples") generated_image_raw = gr.Image(visible=False, type='pil', label="Erstelle Weihnachtskarte...", width=1280, value="resources/init.png", interactive=False, show_share_button=False, show_download_button=False ) generated_image_overlayed = gr.Image(label="Weihnachtskarte", type='pil', width=1280, value=pil_image_with_overlay(Image.open("resources/init.png"), toggle_greet.value, greet.value)) toggle_greet.change(fn=toggle_greet_visibility, inputs=[toggle_greet], outputs=[greet, greet_examples_column], queue=False)\ .then(fn=make_overlay, inputs=[generated_image_raw, toggle_greet, greet], outputs=[generated_image_overlayed], queue=False) greet.change(fn=debounce, outputs=[generated_image_overlayed], queue=False)\ .then(fn=make_overlay, inputs=[generated_image_raw, toggle_greet, greet], outputs=[generated_image_overlayed], queue=False) run_button.click(fn=generate, inputs=[prompt, style_selection], outputs=[run_button, progress_html, generated_image_raw, generated_image_overlayed])\ .then(fn=make_overlay, inputs=[generated_image_raw, toggle_greet, greet], outputs=[generated_image_overlayed], queue=False) shared.gradio_root.queue(concurrency_count=1, api_open=False) shared.gradio_root.launch(server_name="0.0.0.0", show_api=False)