| 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) | |