Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -26,6 +26,8 @@ from diffusers import (
|
|
26 |
EulerDiscreteScheduler,
|
27 |
)
|
28 |
|
|
|
|
|
29 |
qrcode_generator = qrcode.QRCode(
|
30 |
version=1,
|
31 |
error_correction=qrcode.ERROR_CORRECT_H,
|
@@ -33,25 +35,38 @@ qrcode_generator = qrcode.QRCode(
|
|
33 |
border=4,
|
34 |
)
|
35 |
|
36 |
-
controlnet = ControlNetModel.from_pretrained(
|
37 |
-
#"monster-labs/control_v1p_sd15_qrcode_monster",
|
38 |
-
#"DionTimmer/controlnet_qrcode-control_v1p_sd15",
|
39 |
-
"DionTimmer/controlnet_qrcode",
|
40 |
-
torch_dtype=torch.float16
|
41 |
-
).to("cuda")
|
42 |
-
|
43 |
-
pipe = StableDiffusionControlNetImg2ImgPipeline.from_pretrained(
|
44 |
-
#"digiplay/GhostMixV1.2VAE",
|
45 |
-
#"benjamin-paine/stable-diffusion-v1-5",
|
46 |
-
"ckpt/sd15",
|
47 |
-
controlnet = controlnet,
|
48 |
-
torch_dtype = torch.float16,
|
49 |
-
safety_checker = None,
|
50 |
-
).to("cuda")
|
51 |
-
#pipe.enable_xformers_memory_efficient_attention()
|
52 |
-
#pipe.scheduler = DDIMScheduler.from_config(pipe.scheduler.config)
|
53 |
-
#pipe.enable_model_cpu_offload()
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
56 |
def resize_for_condition_image(input_image: Image.Image, resolution: int):
|
57 |
input_image = input_image.convert("RGB")
|
@@ -148,8 +163,14 @@ def inference(
|
|
148 |
bg_color: str = "white",
|
149 |
qr_color: str = "black",
|
150 |
invert_final_image: bool = False,
|
|
|
|
|
|
|
151 |
):
|
152 |
try:
|
|
|
|
|
|
|
153 |
if prompt is None or prompt == "":
|
154 |
raise gr.Error("Prompt is required")
|
155 |
|
@@ -158,7 +179,9 @@ def inference(
|
|
158 |
|
159 |
pipe.scheduler = SAMPLER_MAP[sampler](pipe.scheduler.config)
|
160 |
|
161 |
-
|
|
|
|
|
162 |
|
163 |
if qr_code_content != "" or qrcode_image.size == (1, 1):
|
164 |
print("Generating QR Code from content")
|
@@ -191,6 +214,10 @@ def inference(
|
|
191 |
if init_image is not None:
|
192 |
strength = min(strength, 0.8) # Cap strength at 0.8 when using init_image
|
193 |
|
|
|
|
|
|
|
|
|
194 |
out = pipe(
|
195 |
prompt=prompt,
|
196 |
negative_prompt=negative_prompt,
|
@@ -210,13 +237,19 @@ def inference(
|
|
210 |
if invert_final_image:
|
211 |
final_image = invert_image(final_image)
|
212 |
|
213 |
-
return final_image
|
214 |
except Exception as e:
|
215 |
print(f"Error in inference: {str(e)}")
|
216 |
-
# Return a blank image in case of an error
|
217 |
-
return Image.new('RGB', (768, 768), color='white')
|
218 |
-
|
219 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
220 |
|
221 |
with gr.Blocks(theme='Hev832/Applio') as blocks:
|
222 |
gr.Markdown(
|
@@ -261,7 +294,7 @@ with gr.Blocks(theme='Hev832/Applio') as blocks:
|
|
261 |
prompt = gr.Textbox(
|
262 |
label="Artistic Prompt",
|
263 |
placeholder="Describe the style or theme for your QR code art",
|
264 |
-
info="Be specific and creative! This guides the AI in creating your unique QR art.",
|
265 |
)
|
266 |
negative_prompt = gr.Textbox(
|
267 |
label="Elements to Avoid",
|
@@ -277,7 +310,13 @@ with gr.Blocks(theme='Hev832/Applio') as blocks:
|
|
277 |
)
|
278 |
with gr.Accordion(label="Init Images (Optional)", open=False, visible=True) as init_image_acc:
|
279 |
init_image = gr.Image(label="Init Image (Optional). Leave blank to generate image with AI", type="pil")
|
280 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
281 |
|
282 |
with gr.Accordion("Advanced Art Controls", open=True):
|
283 |
|
@@ -396,11 +435,25 @@ with gr.Blocks(theme='Hev832/Applio') as blocks:
|
|
396 |
value=False,
|
397 |
info="Check this to invert the colors of the final image"
|
398 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
399 |
with gr.Row():
|
400 |
run_btn = gr.Button("🎨 Create Your QR Art", variant="primary")
|
401 |
|
402 |
with gr.Column():
|
403 |
result_image = gr.Image(label="Your Artistic QR Code")
|
|
|
404 |
with gr.Row():
|
405 |
scan_button = gr.Button("Scan QR Code")
|
406 |
invert_button = gr.Button("Invert Image")
|
@@ -446,6 +499,12 @@ with gr.Blocks(theme='Hev832/Applio') as blocks:
|
|
446 |
outputs=[result_image]
|
447 |
)
|
448 |
|
|
|
|
|
|
|
|
|
|
|
|
|
449 |
run_btn.click(
|
450 |
inference,
|
451 |
inputs=[
|
@@ -463,8 +522,11 @@ with gr.Blocks(theme='Hev832/Applio') as blocks:
|
|
463 |
bg_color,
|
464 |
qr_color,
|
465 |
invert_final_image,
|
|
|
|
|
|
|
466 |
],
|
467 |
-
outputs=[result_image],
|
468 |
concurrency_limit=20
|
469 |
)
|
470 |
|
|
|
26 |
EulerDiscreteScheduler,
|
27 |
)
|
28 |
|
29 |
+
|
30 |
+
|
31 |
qrcode_generator = qrcode.QRCode(
|
32 |
version=1,
|
33 |
error_correction=qrcode.ERROR_CORRECT_H,
|
|
|
35 |
border=4,
|
36 |
)
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
|
39 |
+
# Define available models
|
40 |
+
CONTROLNET_MODELS = {
|
41 |
+
"QR Code Monster": "monster-labs/control_v1p_sd15_qrcode_monster",
|
42 |
+
"QR Code": "DionTimmer/controlnet_qrcode",
|
43 |
+
# Add more ControlNet models here
|
44 |
+
}
|
45 |
+
|
46 |
+
DIFFUSION_MODELS = {
|
47 |
+
"Stable Diffusion v1.5": "runwayml/stable-diffusion-v1-5",
|
48 |
+
"GhostMix v1.2": "digiplay/GhostMixV1.2VAE",
|
49 |
+
# Add more diffusion models here
|
50 |
+
}
|
51 |
+
|
52 |
+
def load_models(controlnet_model, diffusion_model):
|
53 |
+
hf_token = get_hf_token()
|
54 |
+
|
55 |
+
controlnet = ControlNetModel.from_pretrained(
|
56 |
+
CONTROLNET_MODELS[controlnet_model],
|
57 |
+
use_auth_token=hf_token,
|
58 |
+
torch_dtype=torch.float16
|
59 |
+
).to("cuda")
|
60 |
+
|
61 |
+
pipe = StableDiffusionControlNetImg2ImgPipeline.from_pretrained(
|
62 |
+
DIFFUSION_MODELS[diffusion_model],
|
63 |
+
controlnet=controlnet,
|
64 |
+
use_auth_token=hf_token,
|
65 |
+
torch_dtype=torch.float16,
|
66 |
+
safety_checker=None,
|
67 |
+
).to("cuda")
|
68 |
+
|
69 |
+
return pipe
|
70 |
|
71 |
def resize_for_condition_image(input_image: Image.Image, resolution: int):
|
72 |
input_image = input_image.convert("RGB")
|
|
|
163 |
bg_color: str = "white",
|
164 |
qr_color: str = "black",
|
165 |
invert_final_image: bool = False,
|
166 |
+
invert_init_image: bool = False, # New parameter
|
167 |
+
controlnet_model: str = "QR Code Monster",
|
168 |
+
diffusion_model: str = "Stable Diffusion v1.5",
|
169 |
):
|
170 |
try:
|
171 |
+
# Load models based on user selection
|
172 |
+
pipe = load_models(controlnet_model, diffusion_model)
|
173 |
+
|
174 |
if prompt is None or prompt == "":
|
175 |
raise gr.Error("Prompt is required")
|
176 |
|
|
|
179 |
|
180 |
pipe.scheduler = SAMPLER_MAP[sampler](pipe.scheduler.config)
|
181 |
|
182 |
+
if seed == -1:
|
183 |
+
seed = torch.randint(0, 2**32 - 1, (1,)).item()
|
184 |
+
generator = torch.manual_seed(seed)
|
185 |
|
186 |
if qr_code_content != "" or qrcode_image.size == (1, 1):
|
187 |
print("Generating QR Code from content")
|
|
|
214 |
if init_image is not None:
|
215 |
strength = min(strength, 0.8) # Cap strength at 0.8 when using init_image
|
216 |
|
217 |
+
# Invert init_image if requested
|
218 |
+
if invert_init_image and init_image is not None:
|
219 |
+
init_image = invert_image(init_image)
|
220 |
+
|
221 |
out = pipe(
|
222 |
prompt=prompt,
|
223 |
negative_prompt=negative_prompt,
|
|
|
237 |
if invert_final_image:
|
238 |
final_image = invert_image(final_image)
|
239 |
|
240 |
+
return final_image, seed
|
241 |
except Exception as e:
|
242 |
print(f"Error in inference: {str(e)}")
|
243 |
+
# Return a blank image and -1 as seed in case of an error
|
244 |
+
return Image.new('RGB', (768, 768), color='white'), -1
|
|
|
245 |
|
246 |
+
def invert_init_image_display(image):
|
247 |
+
if image is None:
|
248 |
+
return None
|
249 |
+
inverted = invert_image(image)
|
250 |
+
if isinstance(inverted, np.ndarray):
|
251 |
+
return Image.fromarray(inverted)
|
252 |
+
return inverted
|
253 |
|
254 |
with gr.Blocks(theme='Hev832/Applio') as blocks:
|
255 |
gr.Markdown(
|
|
|
294 |
prompt = gr.Textbox(
|
295 |
label="Artistic Prompt",
|
296 |
placeholder="Describe the style or theme for your QR code art",
|
297 |
+
info="Be specific and creative! This guides the AI in creating your unique QR code art.",
|
298 |
)
|
299 |
negative_prompt = gr.Textbox(
|
300 |
label="Elements to Avoid",
|
|
|
310 |
)
|
311 |
with gr.Accordion(label="Init Images (Optional)", open=False, visible=True) as init_image_acc:
|
312 |
init_image = gr.Image(label="Init Image (Optional). Leave blank to generate image with AI", type="pil")
|
313 |
+
with gr.Row():
|
314 |
+
invert_init_image = gr.Checkbox(
|
315 |
+
label="Invert Init Image",
|
316 |
+
value=False,
|
317 |
+
info="Check this to invert the colors of the init image"
|
318 |
+
)
|
319 |
+
invert_init_image_button = gr.Button("Invert Init Image")
|
320 |
|
321 |
with gr.Accordion("Advanced Art Controls", open=True):
|
322 |
|
|
|
435 |
value=False,
|
436 |
info="Check this to invert the colors of the final image"
|
437 |
)
|
438 |
+
with gr.Accordion("Model Selection", open=True):
|
439 |
+
controlnet_model_dropdown = gr.Dropdown(
|
440 |
+
choices=list(CONTROLNET_MODELS.keys()),
|
441 |
+
value="QR Code Monster",
|
442 |
+
label="ControlNet Model",
|
443 |
+
info="Select the ControlNet model for QR code generation"
|
444 |
+
)
|
445 |
+
diffusion_model_dropdown = gr.Dropdown(
|
446 |
+
choices=list(DIFFUSION_MODELS.keys()),
|
447 |
+
value="Stable Diffusion v1.5",
|
448 |
+
label="Diffusion Model",
|
449 |
+
info="Select the main diffusion model for image generation"
|
450 |
+
)
|
451 |
with gr.Row():
|
452 |
run_btn = gr.Button("🎨 Create Your QR Art", variant="primary")
|
453 |
|
454 |
with gr.Column():
|
455 |
result_image = gr.Image(label="Your Artistic QR Code")
|
456 |
+
used_seed = gr.Number(label="Seed Used", interactive=False)
|
457 |
with gr.Row():
|
458 |
scan_button = gr.Button("Scan QR Code")
|
459 |
invert_button = gr.Button("Invert Image")
|
|
|
499 |
outputs=[result_image]
|
500 |
)
|
501 |
|
502 |
+
invert_init_image_button.click(
|
503 |
+
invert_init_image_display,
|
504 |
+
inputs=[init_image],
|
505 |
+
outputs=[init_image]
|
506 |
+
)
|
507 |
+
|
508 |
run_btn.click(
|
509 |
inference,
|
510 |
inputs=[
|
|
|
522 |
bg_color,
|
523 |
qr_color,
|
524 |
invert_final_image,
|
525 |
+
invert_init_image,
|
526 |
+
controlnet_model_dropdown,
|
527 |
+
diffusion_model_dropdown,
|
528 |
],
|
529 |
+
outputs=[result_image, used_seed],
|
530 |
concurrency_limit=20
|
531 |
)
|
532 |
|