Update app.py
Browse files
app.py
CHANGED
|
@@ -22,33 +22,32 @@ import numpy as np
|
|
| 22 |
# Configuration Section (Modify here to expand)
|
| 23 |
# ======================
|
| 24 |
|
| 25 |
-
# 1. Base Model - Using reliable SDXL models
|
| 26 |
BASE_MODELS = {
|
| 27 |
-
"sdxl_base": "stabilityai/stable-diffusion-xl-base-1.0", #
|
| 28 |
-
"realistic_vision": "SG161222/RealVisXL_V4.0", #
|
| 29 |
-
"
|
| 30 |
-
"
|
|
|
|
| 31 |
}
|
| 32 |
|
| 33 |
-
# Current model selection
|
| 34 |
-
CURRENT_MODEL_KEY = "
|
| 35 |
BASE_MODEL = BASE_MODELS[CURRENT_MODEL_KEY]
|
| 36 |
|
| 37 |
-
# 2. Fixed LoRAs (Auto-loaded, not user-selectable) - Using actual
|
| 38 |
FIXED_LORAS = {
|
| 39 |
-
"
|
| 40 |
-
"repo_id": "
|
| 41 |
-
"
|
| 42 |
"weight": 0.6,
|
| 43 |
-
"trigger_words": "high quality, detailed,
|
| 44 |
-
"enabled": False # Disabled for now due to compatibility
|
| 45 |
},
|
| 46 |
-
"
|
| 47 |
-
"repo_id": "
|
| 48 |
-
"
|
| 49 |
-
"weight": 0.
|
| 50 |
-
"trigger_words": "
|
| 51 |
-
"enabled": False # Optional, can cause issues
|
| 52 |
}
|
| 53 |
}
|
| 54 |
|
|
@@ -61,7 +60,7 @@ STYLE_PROMPTS = {
|
|
| 61 |
"Watercolor": "watercolor painting, soft brush strokes, translucent layers, artistic, painterly, paper texture, traditional art, masterpiece, ",
|
| 62 |
}
|
| 63 |
|
| 64 |
-
# 4. Optional LoRAs (User-selectable) - Using verified
|
| 65 |
OPTIONAL_LORAS = {
|
| 66 |
"None": {
|
| 67 |
"repo_id": None,
|
|
@@ -69,35 +68,41 @@ OPTIONAL_LORAS = {
|
|
| 69 |
"trigger_words": "",
|
| 70 |
"description": "No additional LoRA"
|
| 71 |
},
|
| 72 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
"repo_id": "latent-consistency/lcm-lora-sdxl",
|
| 74 |
"weight": 0.8,
|
| 75 |
"trigger_words": "lcm style, high quality",
|
| 76 |
-
"description": "
|
| 77 |
},
|
| 78 |
-
"
|
| 79 |
"repo_id": "nerijs/pixel-art-xl",
|
| 80 |
-
"weight": 0.
|
| 81 |
-
"trigger_words": "
|
| 82 |
-
"description": "
|
| 83 |
},
|
| 84 |
-
"
|
| 85 |
-
"repo_id": "
|
| 86 |
"weight": 0.8,
|
| 87 |
-
"trigger_words": "
|
| 88 |
-
"description": "
|
| 89 |
},
|
| 90 |
-
"
|
| 91 |
-
"repo_id": "
|
| 92 |
-
"weight": 0.
|
| 93 |
-
"trigger_words": "
|
| 94 |
-
"description": "
|
| 95 |
},
|
| 96 |
-
"
|
| 97 |
-
"repo_id": "ostris/
|
| 98 |
-
"weight": 0.
|
| 99 |
-
"trigger_words": "
|
| 100 |
-
"description": "
|
| 101 |
}
|
| 102 |
}
|
| 103 |
|
|
@@ -392,15 +397,13 @@ def generate_image(
|
|
| 392 |
|
| 393 |
return (
|
| 394 |
image,
|
| 395 |
-
metadata_str
|
| 396 |
-
f"{filename_base}.webp",
|
| 397 |
-
f"{filename_base}.txt"
|
| 398 |
)
|
| 399 |
|
| 400 |
except Exception as e:
|
| 401 |
error_msg = f"Generation failed: {str(e)}"
|
| 402 |
print(f"❌ {error_msg}")
|
| 403 |
-
return None, error_msg
|
| 404 |
|
| 405 |
# ======================
|
| 406 |
# Gradio Interface
|
|
@@ -581,16 +584,9 @@ def create_interface():
|
|
| 581 |
format="webp"
|
| 582 |
)
|
| 583 |
|
| 584 |
-
#
|
| 585 |
with gr.Row():
|
| 586 |
-
|
| 587 |
-
"⬇️ Download Image (WebP)",
|
| 588 |
-
variant="secondary"
|
| 589 |
-
)
|
| 590 |
-
download_meta_btn = gr.DownloadButton(
|
| 591 |
-
"⬇️ Download Metadata (TXT)",
|
| 592 |
-
variant="secondary"
|
| 593 |
-
)
|
| 594 |
|
| 595 |
# k. Metadata Display
|
| 596 |
metadata_output = gr.Textbox(
|
|
@@ -620,27 +616,36 @@ def create_interface():
|
|
| 620 |
if result[0] is not None: # Success
|
| 621 |
image, metadata, img_filename, meta_filename = result
|
| 622 |
|
| 623 |
-
#
|
| 624 |
-
|
| 625 |
-
|
| 626 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 627 |
|
| 628 |
-
|
| 629 |
-
|
| 630 |
-
|
|
|
|
|
|
|
|
|
|
| 631 |
|
| 632 |
return (
|
| 633 |
image,
|
| 634 |
metadata,
|
| 635 |
-
|
| 636 |
-
|
| 637 |
)
|
| 638 |
else: # Error
|
| 639 |
return result[0], result[1], None, None
|
|
|
|
|
|
|
| 640 |
|
| 641 |
-
# Generate button click
|
| 642 |
generate_btn.click(
|
| 643 |
-
fn=
|
| 644 |
inputs=[
|
| 645 |
prompt_input, negative_prompt_input, style_radio,
|
| 646 |
seed_input, width_input, height_input,
|
|
@@ -648,8 +653,7 @@ def create_interface():
|
|
| 648 |
steps_slider, cfg_slider, language_dropdown
|
| 649 |
],
|
| 650 |
outputs=[
|
| 651 |
-
image_output, metadata_output
|
| 652 |
-
download_img_btn, download_meta_btn
|
| 653 |
]
|
| 654 |
)
|
| 655 |
|
|
|
|
| 22 |
# Configuration Section (Modify here to expand)
|
| 23 |
# ======================
|
| 24 |
|
| 25 |
+
# 1. Base Model - Using reliable SDXL models (avoiding incomplete "bait" models)
|
| 26 |
BASE_MODELS = {
|
| 27 |
+
"sdxl_base": "stabilityai/stable-diffusion-xl-base-1.0", # Most reliable choice
|
| 28 |
+
"realistic_vision": "SG161222/RealVisXL_V4.0", # High-quality realistic model
|
| 29 |
+
"anime_xl": "Linaqruf/animagine-xl-3.1", # Popular anime-style SDXL
|
| 30 |
+
"juggernaut_xl": "RunDiffusion/Juggernaut-XL-v9", # High-quality general purpose
|
| 31 |
+
"playground_v2": "playgroundai/playground-v2.5-1024px-aesthetic" # Aesthetic focused
|
| 32 |
}
|
| 33 |
|
| 34 |
+
# Current model selection (change this to switch models)
|
| 35 |
+
CURRENT_MODEL_KEY = "realistic_vision" # Changed to working model
|
| 36 |
BASE_MODEL = BASE_MODELS[CURRENT_MODEL_KEY]
|
| 37 |
|
| 38 |
+
# 2. Fixed LoRAs (Auto-loaded, not user-selectable) - Using actual LoRA models
|
| 39 |
FIXED_LORAS = {
|
| 40 |
+
"detail_enhancer": {
|
| 41 |
+
"repo_id": "ostris/ikea-instructions-lora-sdxl", # Real LoRA for details
|
| 42 |
+
"filename": None,
|
| 43 |
"weight": 0.6,
|
| 44 |
+
"trigger_words": "high quality, detailed, sharp focus"
|
|
|
|
| 45 |
},
|
| 46 |
+
"quality_boost": {
|
| 47 |
+
"repo_id": "stabilityai/stable-diffusion-xl-offset-example-lora", # Official SDXL LoRA
|
| 48 |
+
"filename": None,
|
| 49 |
+
"weight": 0.5,
|
| 50 |
+
"trigger_words": "masterpiece, best quality"
|
|
|
|
| 51 |
}
|
| 52 |
}
|
| 53 |
|
|
|
|
| 60 |
"Watercolor": "watercolor painting, soft brush strokes, translucent layers, artistic, painterly, paper texture, traditional art, masterpiece, ",
|
| 61 |
}
|
| 62 |
|
| 63 |
+
# 4. Optional LoRAs (User-selectable via dropdown, can select multiple) - Using real, verified LoRAs
|
| 64 |
OPTIONAL_LORAS = {
|
| 65 |
"None": {
|
| 66 |
"repo_id": None,
|
|
|
|
| 68 |
"trigger_words": "",
|
| 69 |
"description": "No additional LoRA"
|
| 70 |
},
|
| 71 |
+
"Offset Noise LoRA": {
|
| 72 |
+
"repo_id": "stabilityai/stable-diffusion-xl-offset-example-lora",
|
| 73 |
+
"weight": 0.7,
|
| 74 |
+
"trigger_words": "high contrast, dramatic lighting",
|
| 75 |
+
"description": "Enhanced contrast and lighting (Official Stability AI)"
|
| 76 |
+
},
|
| 77 |
+
"LCM LoRA": {
|
| 78 |
"repo_id": "latent-consistency/lcm-lora-sdxl",
|
| 79 |
"weight": 0.8,
|
| 80 |
"trigger_words": "lcm style, high quality",
|
| 81 |
+
"description": "Latent Consistency Model for faster generation"
|
| 82 |
},
|
| 83 |
+
"Pixel Art LoRA": {
|
| 84 |
"repo_id": "nerijs/pixel-art-xl",
|
| 85 |
+
"weight": 0.9,
|
| 86 |
+
"trigger_words": "pixel art style, 8bit, retro game",
|
| 87 |
+
"description": "Pixel art style transformation"
|
| 88 |
},
|
| 89 |
+
"Watercolor LoRA": {
|
| 90 |
+
"repo_id": "ostris/watercolor-style-lora-sdxl",
|
| 91 |
"weight": 0.8,
|
| 92 |
+
"trigger_words": "watercolor painting, soft colors, artistic",
|
| 93 |
+
"description": "Watercolor painting style"
|
| 94 |
},
|
| 95 |
+
"Sketch LoRA": {
|
| 96 |
+
"repo_id": "ostris/crayon-style-lora-sdxl",
|
| 97 |
+
"weight": 0.7,
|
| 98 |
+
"trigger_words": "sketch style, pencil drawing, artistic",
|
| 99 |
+
"description": "Hand-drawn sketch style"
|
| 100 |
},
|
| 101 |
+
"Portrait LoRA": {
|
| 102 |
+
"repo_id": "ostris/face-helper-sdxl-lora",
|
| 103 |
+
"weight": 0.8,
|
| 104 |
+
"trigger_words": "portrait, beautiful face, detailed eyes",
|
| 105 |
+
"description": "Portrait and face enhancement"
|
| 106 |
}
|
| 107 |
}
|
| 108 |
|
|
|
|
| 397 |
|
| 398 |
return (
|
| 399 |
image,
|
| 400 |
+
metadata_str
|
|
|
|
|
|
|
| 401 |
)
|
| 402 |
|
| 403 |
except Exception as e:
|
| 404 |
error_msg = f"Generation failed: {str(e)}"
|
| 405 |
print(f"❌ {error_msg}")
|
| 406 |
+
return None, error_msg
|
| 407 |
|
| 408 |
# ======================
|
| 409 |
# Gradio Interface
|
|
|
|
| 584 |
format="webp"
|
| 585 |
)
|
| 586 |
|
| 587 |
+
# Simplified UI without complex download buttons
|
| 588 |
with gr.Row():
|
| 589 |
+
gr.Markdown("**Right-click the image above to download**")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 590 |
|
| 591 |
# k. Metadata Display
|
| 592 |
metadata_output = gr.Textbox(
|
|
|
|
| 616 |
if result[0] is not None: # Success
|
| 617 |
image, metadata, img_filename, meta_filename = result
|
| 618 |
|
| 619 |
+
# Save files temporarily for download
|
| 620 |
+
import tempfile
|
| 621 |
+
import os
|
| 622 |
+
|
| 623 |
+
# Create temporary files
|
| 624 |
+
temp_dir = tempfile.mkdtemp()
|
| 625 |
+
img_path = os.path.join(temp_dir, img_filename)
|
| 626 |
+
meta_path = os.path.join(temp_dir, meta_filename)
|
| 627 |
|
| 628 |
+
# Save image
|
| 629 |
+
image.save(img_path, format="WEBP", quality=95)
|
| 630 |
+
|
| 631 |
+
# Save metadata
|
| 632 |
+
with open(meta_path, 'w', encoding='utf-8') as f:
|
| 633 |
+
f.write(metadata)
|
| 634 |
|
| 635 |
return (
|
| 636 |
image,
|
| 637 |
metadata,
|
| 638 |
+
img_path, # File path for download
|
| 639 |
+
meta_path # File path for download
|
| 640 |
)
|
| 641 |
else: # Error
|
| 642 |
return result[0], result[1], None, None
|
| 643 |
+
else: # Error
|
| 644 |
+
return result[0], result[1], None, None
|
| 645 |
|
| 646 |
+
# Generate button click - Simplified without complex downloads
|
| 647 |
generate_btn.click(
|
| 648 |
+
fn=generate_image,
|
| 649 |
inputs=[
|
| 650 |
prompt_input, negative_prompt_input, style_radio,
|
| 651 |
seed_input, width_input, height_input,
|
|
|
|
| 653 |
steps_slider, cfg_slider, language_dropdown
|
| 654 |
],
|
| 655 |
outputs=[
|
| 656 |
+
image_output, metadata_output
|
|
|
|
| 657 |
]
|
| 658 |
)
|
| 659 |
|