File size: 9,236 Bytes
33adbe7
03fc011
b47a274
796cb1f
b47a274
 
796cb1f
 
 
b47a274
 
cc1aefe
 
 
 
35f1465
 
cc1aefe
 
b47a274
34a218b
41b1d8d
 
796cb1f
34a218b
 
 
 
 
796cb1f
34a218b
796cb1f
 
 
 
 
 
41b1d8d
 
796cb1f
34a218b
41b1d8d
 
796cb1f
 
 
cc1aefe
 
 
99a9568
cc1aefe
99a9568
41b1d8d
 
 
 
 
 
 
 
 
99a9568
 
50754bf
99a9568
b47a274
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99a9568
b47a274
340c367
b47a274
 
0276c07
34a218b
 
03fc011
34a218b
cc1aefe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41b1d8d
cc1aefe
 
 
99a9568
cc1aefe
 
 
 
 
 
 
 
 
 
 
 
 
af2c332
34a218b
cc1aefe
41b1d8d
 
 
 
 
 
 
 
34a218b
 
 
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
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")
PROMPT_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"]]
EXAMPLE_GREETINGS = [ 
    "Ich wünsche dir von Herzen ein frohes Fest.",
    "Frohes Fest und viele glückliche Momente mit deinen Liebsten!",
    "Zauberhafte Weihnachten für dich!"
]

def generate(*args):
    yield gr.update(value=modules.html.make_progress_html(1, "0/30")), \
          gr.update()

    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(value=modules.html.make_progress_html(percentage, title)), \
                      gr.update(value=image) if image is not None else gr.update()
            if flag == 'results':
                image = product[0]
                yield gr.update(value=""), \
                      gr.update(value=image)
                finished = True
    return

def translate_promt_example(prompt_de):
    return [x for x in PROMPT_EXAMPLES if x[0] == prompt_de][0][1]

def toggle_greet_visibility(is_visible):
    return gr.update(visible=is_visible)

def __toggle_generate_state(is_preview):
    return gr.update(visible=is_preview), gr.update(visible=not is_preview), gr.update(interactive=not is_preview)

def prepare_generate():
    return __toggle_generate_state(True)

def finish_generate():
    return __toggle_generate_state(False)

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
    """)
    with gr.Accordion("Info", elem_classes='panel-container', open=False):
        with gr.Column():
            gr.Markdown("""
            * 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 [HuggingFace](https://huggingface.co/spaces/QualityMinds/Weihnachtskarten/tree/main) verfügbar.
            """)

    with gr.Row(elem_classes='panel-container'):
        with gr.Column():
            with gr.Row():
                with gr.Column(scale=5):
                    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, container=False, lines=2)
                with gr.Column(scale=1, min_width="80px"):
                    gr.Markdown("##### Stil", elem_classes="input-label")
                    style_selection = gr.Dropdown(choices=style_keys, value='Kinofilm', container=False, elem_id="style-selection")
                with gr.Column(scale=1, min_width="80px"):
                    progress_html = gr.HTML(visible=True, elem_id='progress-bar', elem_classes='progress-bar')
                    run_button = gr.Button(value="Weihnachtskarte\nerstellen", variant='primary', elem_id='generate-button', )
            with gr.Row():
                promt_example_de = gr.Textbox(visible=False)
                gr.Examples(elem_id="prompt-examples", examples=PROMPT_EXAMPLES, inputs=[promt_example_de], cache_examples=False)
    
    toggle_greet = gr.Checkbox(label="Persönliche Weihnachtsgrüße hinzufügen", elem_id="toggle-greet-checkbox",
                               container=False, value=True, interactive=True)

    greeting_row=gr.Row(elem_classes='panel-container')
    with greeting_row:
        with gr.Column():
            greet = gr.Textbox(value=EXAMPLE_GREETINGS[0], placeholder="", interactive=True, container=False, lines=2, max_lines=2)
            greet_examples = gr.Examples(elem_id="greet-examples", examples=EXAMPLE_GREETINGS, inputs=[greet])


    generated_image_raw = gr.Image(visible=False, type='pil', label="Erstelle Weihnachtskarte...", elem_classes="generated-image", 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', elem_classes="generated-image", width=1280,
                                         value=pil_image_with_overlay(Image.open("resources/init.png"), toggle_greet.value, greet.value))

    promt_example_de.change(fn=translate_promt_example, inputs=[promt_example_de], outputs=[prompt], queue=False)
    toggle_greet.change(fn=toggle_greet_visibility, inputs=[toggle_greet], outputs=[greeting_row], queue=False, show_progress=False)\
                .then(fn=make_overlay, inputs=[generated_image_raw, toggle_greet, greet], outputs=[generated_image_overlayed], show_progress=False, queue=False)
    greet.change(fn=debounce, outputs=[generated_image_overlayed], queue=False, show_progress=False)\
         .then(fn=make_overlay, inputs=[generated_image_raw, toggle_greet, greet], outputs=[generated_image_overlayed], queue=False, show_progress=False)
    run_button.click(fn=prepare_generate, outputs=[generated_image_raw, generated_image_overlayed, run_button], queue=False)\
              .then(fn=generate, inputs=[prompt, style_selection], outputs=[progress_html, generated_image_raw], queue=True)\
              .then(fn=make_overlay, inputs=[generated_image_raw, toggle_greet, greet], outputs=[generated_image_overlayed], queue=False)\
              .then(fn=finish_generate, outputs=[generated_image_raw, generated_image_overlayed, run_button], 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)