Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
|
@@ -40,7 +40,7 @@ qrcode_generator = qrcode.QRCode(
|
|
| 40 |
|
| 41 |
# Define available models
|
| 42 |
CONTROLNET_MODELS = {
|
| 43 |
-
"QR Code Monster": "monster-labs/control_v1p_sd15_qrcode_monster",
|
| 44 |
"QR Code": "DionTimmer/controlnet_qrcode-control_v1p_sd15",
|
| 45 |
# Add more ControlNet models here
|
| 46 |
}
|
|
@@ -68,7 +68,7 @@ def load_models_on_launch():
|
|
| 68 |
loaded_controlnet = ControlNetModel.from_pretrained(
|
| 69 |
controlnet_path,
|
| 70 |
torch_dtype=torch.float16
|
| 71 |
-
).to("
|
| 72 |
|
| 73 |
diffusion_path = snapshot_download(DIFFUSION_MODELS["GhostMix"])
|
| 74 |
loaded_pipe = StableDiffusionControlNetImg2ImgPipeline.from_pretrained(
|
|
@@ -76,7 +76,7 @@ def load_models_on_launch():
|
|
| 76 |
controlnet=loaded_controlnet,
|
| 77 |
torch_dtype=torch.float16,
|
| 78 |
safety_checker=None,
|
| 79 |
-
).to("
|
| 80 |
print("Models loaded successfully!")
|
| 81 |
|
| 82 |
# Modify the load_models function to use global variables
|
|
@@ -182,7 +182,7 @@ def invert_displayed_image(image):
|
|
| 182 |
return inverted
|
| 183 |
|
| 184 |
|
| 185 |
-
MAX_TOKENS =
|
| 186 |
|
| 187 |
def count_tokens(text):
|
| 188 |
"""Count the number of tokens in the text."""
|
|
@@ -193,20 +193,21 @@ def inference(
|
|
| 193 |
qr_code_content: str,
|
| 194 |
prompt: str,
|
| 195 |
negative_prompt: str,
|
| 196 |
-
guidance_scale: float =
|
| 197 |
-
controlnet_conditioning_scale: float =
|
| 198 |
-
strength: float = 0.
|
| 199 |
seed: int = -1,
|
| 200 |
init_image: Image.Image | None = None,
|
| 201 |
qrcode_image: Image.Image | None = None,
|
| 202 |
use_qr_code_as_init_image = True,
|
| 203 |
-
sampler = "DPM++ Karras SDE",
|
| 204 |
bg_color: str = "white",
|
| 205 |
qr_color: str = "black",
|
| 206 |
invert_final_image: bool = False,
|
| 207 |
invert_init_image: bool = False,
|
| 208 |
controlnet_model: str = "QR Code Monster",
|
| 209 |
diffusion_model: str = "GhostMix",
|
|
|
|
| 210 |
):
|
| 211 |
try:
|
| 212 |
progress = gr.Progress()
|
|
@@ -262,19 +263,18 @@ def inference(
|
|
| 262 |
strength = 1.0
|
| 263 |
|
| 264 |
# Adjust strength if using an init_image
|
| 265 |
-
if init_image is not None:
|
| 266 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 267 |
|
| 268 |
# Invert init_image if requested
|
| 269 |
if invert_init_image and init_image is not None:
|
| 270 |
init_image = invert_image(init_image)
|
| 271 |
|
| 272 |
-
# Commenting out the prompt splitting
|
| 273 |
-
# prompt_chunks = split_prompt(prompt)
|
| 274 |
-
# negative_prompt_chunks = split_prompt(negative_prompt)
|
| 275 |
-
|
| 276 |
final_image = None
|
| 277 |
-
# for prompt_chunk, negative_prompt_chunk in zip(prompt_chunks, negative_prompt_chunks):
|
| 278 |
out = pipe(
|
| 279 |
prompt=prompt, # Use the full prompt
|
| 280 |
negative_prompt=negative_prompt, # Use the full negative prompt
|
|
@@ -286,7 +286,7 @@ def inference(
|
|
| 286 |
controlnet_conditioning_scale=float(controlnet_conditioning_scale),
|
| 287 |
generator=generator,
|
| 288 |
strength=float(strength),
|
| 289 |
-
num_inference_steps=
|
| 290 |
)
|
| 291 |
final_image = out.images[0] if final_image is None else final_image
|
| 292 |
|
|
@@ -301,6 +301,8 @@ def inference(
|
|
| 301 |
print(f"Unexpected error in inference: {str(e)}")
|
| 302 |
return Image.new('RGB', (1024, 1024), color='white'), -1
|
| 303 |
|
|
|
|
|
|
|
| 304 |
def split_prompt(prompt, max_length=77):
|
| 305 |
"""Split the prompt into chunks that do not exceed the max_length."""
|
| 306 |
words = prompt.split()
|
|
@@ -579,6 +581,17 @@ with gr.Blocks(theme='Hev832/Applio', css=css) as blocks:
|
|
| 579 |
"""
|
| 580 |
)
|
| 581 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 582 |
def scan_and_display(image):
|
| 583 |
if image is None:
|
| 584 |
return "No image to scan"
|
|
@@ -628,6 +641,22 @@ with gr.Blocks(theme='Hev832/Applio', css=css) as blocks:
|
|
| 628 |
outputs=[result_image]
|
| 629 |
)
|
| 630 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 631 |
run_btn.click(
|
| 632 |
inference,
|
| 633 |
inputs=[
|
|
@@ -647,6 +676,7 @@ with gr.Blocks(theme='Hev832/Applio', css=css) as blocks:
|
|
| 647 |
invert_final_image,
|
| 648 |
controlnet_model_dropdown,
|
| 649 |
diffusion_model_dropdown,
|
|
|
|
| 650 |
],
|
| 651 |
outputs=[result_image, used_seed],
|
| 652 |
concurrency_limit=20
|
|
@@ -656,4 +686,4 @@ with gr.Blocks(theme='Hev832/Applio', css=css) as blocks:
|
|
| 656 |
load_models_on_launch()
|
| 657 |
|
| 658 |
blocks.queue(max_size=20)
|
| 659 |
-
blocks.launch(share=
|
|
|
|
| 40 |
|
| 41 |
# Define available models
|
| 42 |
CONTROLNET_MODELS = {
|
| 43 |
+
"QR Code Monster": "monster-labs/control_v1p_sd15_qrcode_monster/v2/",
|
| 44 |
"QR Code": "DionTimmer/controlnet_qrcode-control_v1p_sd15",
|
| 45 |
# Add more ControlNet models here
|
| 46 |
}
|
|
|
|
| 68 |
loaded_controlnet = ControlNetModel.from_pretrained(
|
| 69 |
controlnet_path,
|
| 70 |
torch_dtype=torch.float16
|
| 71 |
+
).to("mps")
|
| 72 |
|
| 73 |
diffusion_path = snapshot_download(DIFFUSION_MODELS["GhostMix"])
|
| 74 |
loaded_pipe = StableDiffusionControlNetImg2ImgPipeline.from_pretrained(
|
|
|
|
| 76 |
controlnet=loaded_controlnet,
|
| 77 |
torch_dtype=torch.float16,
|
| 78 |
safety_checker=None,
|
| 79 |
+
).to("mps")
|
| 80 |
print("Models loaded successfully!")
|
| 81 |
|
| 82 |
# Modify the load_models function to use global variables
|
|
|
|
| 182 |
return inverted
|
| 183 |
|
| 184 |
|
| 185 |
+
MAX_TOKENS = 78
|
| 186 |
|
| 187 |
def count_tokens(text):
|
| 188 |
"""Count the number of tokens in the text."""
|
|
|
|
| 193 |
qr_code_content: str,
|
| 194 |
prompt: str,
|
| 195 |
negative_prompt: str,
|
| 196 |
+
guidance_scale: float = 15.0,
|
| 197 |
+
controlnet_conditioning_scale: float = 1.5,
|
| 198 |
+
strength: float = 0.6,
|
| 199 |
seed: int = -1,
|
| 200 |
init_image: Image.Image | None = None,
|
| 201 |
qrcode_image: Image.Image | None = None,
|
| 202 |
use_qr_code_as_init_image = True,
|
| 203 |
+
sampler = "DPM++ Karras SDE",
|
| 204 |
bg_color: str = "white",
|
| 205 |
qr_color: str = "black",
|
| 206 |
invert_final_image: bool = False,
|
| 207 |
invert_init_image: bool = False,
|
| 208 |
controlnet_model: str = "QR Code Monster",
|
| 209 |
diffusion_model: str = "GhostMix",
|
| 210 |
+
reference_image_strength: float = 0.6,
|
| 211 |
):
|
| 212 |
try:
|
| 213 |
progress = gr.Progress()
|
|
|
|
| 263 |
strength = 1.0
|
| 264 |
|
| 265 |
# Adjust strength if using an init_image
|
| 266 |
+
if init_image is not None and not use_qr_code_as_init_image:
|
| 267 |
+
# Map the 0-5 range to 0-1 range for the strength parameter
|
| 268 |
+
mapped_strength = min(reference_image_strength / 5.0, 1.0)
|
| 269 |
+
strength = 1.0 - mapped_strength # Invert the strength for img2img
|
| 270 |
+
elif use_qr_code_as_init_image:
|
| 271 |
+
strength = min(strength, 0.6) # Cap strength at 0.6 when using QR code as init_image
|
| 272 |
|
| 273 |
# Invert init_image if requested
|
| 274 |
if invert_init_image and init_image is not None:
|
| 275 |
init_image = invert_image(init_image)
|
| 276 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 277 |
final_image = None
|
|
|
|
| 278 |
out = pipe(
|
| 279 |
prompt=prompt, # Use the full prompt
|
| 280 |
negative_prompt=negative_prompt, # Use the full negative prompt
|
|
|
|
| 286 |
controlnet_conditioning_scale=float(controlnet_conditioning_scale),
|
| 287 |
generator=generator,
|
| 288 |
strength=float(strength),
|
| 289 |
+
num_inference_steps=50,
|
| 290 |
)
|
| 291 |
final_image = out.images[0] if final_image is None else final_image
|
| 292 |
|
|
|
|
| 301 |
print(f"Unexpected error in inference: {str(e)}")
|
| 302 |
return Image.new('RGB', (1024, 1024), color='white'), -1
|
| 303 |
|
| 304 |
+
|
| 305 |
+
|
| 306 |
def split_prompt(prompt, max_length=77):
|
| 307 |
"""Split the prompt into chunks that do not exceed the max_length."""
|
| 308 |
words = prompt.split()
|
|
|
|
| 581 |
"""
|
| 582 |
)
|
| 583 |
|
| 584 |
+
with gr.Row():
|
| 585 |
+
reference_image_strength = gr.Slider(
|
| 586 |
+
minimum=0.0,
|
| 587 |
+
maximum=5.0,
|
| 588 |
+
step=0.05,
|
| 589 |
+
value=0.6,
|
| 590 |
+
label="Reference Image Influence",
|
| 591 |
+
info="Controls how much the reference image influences the final result (0 = ignore, 5 = copy exactly)",
|
| 592 |
+
visible=False # We'll make this visible when a reference image is uploaded
|
| 593 |
+
)
|
| 594 |
+
|
| 595 |
def scan_and_display(image):
|
| 596 |
if image is None:
|
| 597 |
return "No image to scan"
|
|
|
|
| 641 |
outputs=[result_image]
|
| 642 |
)
|
| 643 |
|
| 644 |
+
# Add logic to show/hide the reference_image_strength slider
|
| 645 |
+
def update_reference_image_strength_visibility(init_image, use_qr_code_as_init_image):
|
| 646 |
+
return gr.update(visible=init_image is not None and not use_qr_code_as_init_image)
|
| 647 |
+
|
| 648 |
+
init_image.change(
|
| 649 |
+
update_reference_image_strength_visibility,
|
| 650 |
+
inputs=[init_image, use_qr_code_as_init_image],
|
| 651 |
+
outputs=[reference_image_strength]
|
| 652 |
+
)
|
| 653 |
+
|
| 654 |
+
use_qr_code_as_init_image.change(
|
| 655 |
+
update_reference_image_strength_visibility,
|
| 656 |
+
inputs=[init_image, use_qr_code_as_init_image],
|
| 657 |
+
outputs=[reference_image_strength]
|
| 658 |
+
)
|
| 659 |
+
|
| 660 |
run_btn.click(
|
| 661 |
inference,
|
| 662 |
inputs=[
|
|
|
|
| 676 |
invert_final_image,
|
| 677 |
controlnet_model_dropdown,
|
| 678 |
diffusion_model_dropdown,
|
| 679 |
+
reference_image_strength,
|
| 680 |
],
|
| 681 |
outputs=[result_image, used_seed],
|
| 682 |
concurrency_limit=20
|
|
|
|
| 686 |
load_models_on_launch()
|
| 687 |
|
| 688 |
blocks.queue(max_size=20)
|
| 689 |
+
blocks.launch(share=True, show_api=True)
|