Spaces:
Running
on
Zero
Running
on
Zero
improvements to QR code generation, shareable JSON
Browse files
app.py
CHANGED
|
@@ -22,7 +22,6 @@ hf_hub_download(repo_id="comfyanonymous/ControlNet-v1-1_fp16_safetensors", filen
|
|
| 22 |
hf_hub_download(repo_id="Lykon/dreamshaper-7", filename="vae/diffusion_pytorch_model.fp16.safetensors", local_dir="models")
|
| 23 |
hf_hub_download(repo_id="stabilityai/sd-vae-ft-mse-original", filename="vae-ft-mse-840000-ema-pruned.safetensors", local_dir="models/vae")
|
| 24 |
hf_hub_download(repo_id="lllyasviel/Annotators", filename="RealESRGAN_x4plus.pth", local_dir="models/upscale_models")
|
| 25 |
-
hf_hub_download(repo_id="lykon/RealESRGAN_x4plus", filename="RealESRGAN_x4plus.pth", local_dir="models/upscale_models")
|
| 26 |
|
| 27 |
def get_value_at_index(obj: Union[Sequence, Mapping], index: int) -> Any:
|
| 28 |
"""Returns the value at the given index of a sequence or mapping.
|
|
@@ -195,13 +194,249 @@ def generate_qr_code_unified(prompt: str, text_input: str, input_type: str = "UR
|
|
| 195 |
else: # artistic
|
| 196 |
yield from _pipeline_artistic(prompt, qr_text, input_type, image_size, border_size, error_correction, module_size, module_drawer, actual_seed, enable_upscale, freeu_b1, freeu_b2, freeu_s1, freeu_s2, enable_sag, sag_scale, sag_blur_sigma, controlnet_strength_first, controlnet_strength_final)
|
| 197 |
|
| 198 |
-
def generate_standard_qr(prompt: str, text_input: str, input_type: str = "URL", image_size: int = 512, border_size: int = 4, error_correction: str = "Medium (15%)", module_size: int = 12, module_drawer: str = "Square", use_custom_seed: bool = False, seed: int = 0, enable_upscale: bool = False):
|
| 199 |
"""Wrapper function for standard QR generation"""
|
| 200 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
|
| 202 |
-
def generate_artistic_qr(prompt: str, text_input: str, input_type: str = "URL", image_size: int = 512, border_size: int = 4, error_correction: str = "Medium (15%)", module_size: int = 12, module_drawer: str = "Square", use_custom_seed: bool = False, seed: int = 0, enable_upscale: bool = True, freeu_b1: float = 1.4, freeu_b2: float = 1.3, freeu_s1: float = 0.0, freeu_s2: float = 1.3, enable_sag: bool = True, sag_scale: float = 0.5, sag_blur_sigma: float =
|
| 203 |
"""Wrapper function for artistic QR generation with FreeU and SAG parameters"""
|
| 204 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 205 |
|
| 206 |
def add_noise_to_border_only(image_tensor, seed: int, border_size: int, image_size: int, module_size: int = 12):
|
| 207 |
"""
|
|
@@ -331,7 +566,7 @@ def _pipeline_standard(prompt: str, qr_text: str, input_type: str, image_size: i
|
|
| 331 |
except RuntimeError as e:
|
| 332 |
error_msg = (
|
| 333 |
f"Error generating QR code: {str(e)}\n"
|
| 334 |
-
"Try with a shorter text, increase the image size, or decrease the border size, module size, and error correction level under
|
| 335 |
)
|
| 336 |
yield None, error_msg
|
| 337 |
return
|
|
@@ -453,16 +688,16 @@ def _pipeline_standard(prompt: str, qr_text: str, input_type: str, image_size: i
|
|
| 453 |
image_np = (image_tensor.cpu().numpy() * 255).astype(np.uint8)
|
| 454 |
image_np = image_np[0]
|
| 455 |
pil_image = Image.fromarray(image_np)
|
| 456 |
-
yield pil_image,
|
| 457 |
else:
|
| 458 |
# No upscaling
|
| 459 |
image_tensor = get_value_at_index(vaedecode_21, 0)
|
| 460 |
image_np = (image_tensor.cpu().numpy() * 255).astype(np.uint8)
|
| 461 |
image_np = image_np[0]
|
| 462 |
pil_image = Image.fromarray(image_np)
|
| 463 |
-
yield pil_image,
|
| 464 |
|
| 465 |
-
def _pipeline_artistic(prompt: str, qr_text: str, input_type: str, image_size: int, border_size: int, error_correction: str, module_size: int, module_drawer: str, seed: int, enable_upscale: bool = True, freeu_b1: float = 1.4, freeu_b2: float = 1.3, freeu_s1: float = 0.0, freeu_s2: float = 1.3, enable_sag: bool = True, sag_scale: float = 0.5, sag_blur_sigma: float =
|
| 466 |
# Generate QR code
|
| 467 |
qr_protocol = "None" if input_type == "Plain Text" else "Https"
|
| 468 |
|
|
@@ -481,7 +716,7 @@ def _pipeline_artistic(prompt: str, qr_text: str, input_type: str, image_size: i
|
|
| 481 |
except RuntimeError as e:
|
| 482 |
error_msg = (
|
| 483 |
f"Error generating QR code: {str(e)}\n"
|
| 484 |
-
"Try with a shorter text, increase the image size, or decrease the border size, module size, and error correction level under
|
| 485 |
)
|
| 486 |
yield None, error_msg
|
| 487 |
return
|
|
@@ -620,7 +855,11 @@ def _pipeline_artistic(prompt: str, qr_text: str, input_type: str, image_size: i
|
|
| 620 |
first_pass_np = (first_pass_tensor.cpu().numpy() * 255).astype(np.uint8)
|
| 621 |
first_pass_np = first_pass_np[0]
|
| 622 |
first_pass_pil = Image.fromarray(first_pass_np)
|
| 623 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 624 |
yield first_pass_pil, step_msg
|
| 625 |
|
| 626 |
# Final ControlNet pass (second pass - refinement)
|
|
@@ -683,7 +922,7 @@ def _pipeline_artistic(prompt: str, qr_text: str, input_type: str, image_size: i
|
|
| 683 |
image_np = (image_tensor.cpu().numpy() * 255).astype(np.uint8)
|
| 684 |
image_np = image_np[0]
|
| 685 |
final_image = Image.fromarray(image_np)
|
| 686 |
-
step_msg =
|
| 687 |
yield final_image, step_msg
|
| 688 |
else:
|
| 689 |
# No upscaling
|
|
@@ -691,7 +930,7 @@ def _pipeline_artistic(prompt: str, qr_text: str, input_type: str, image_size: i
|
|
| 691 |
image_np = (image_tensor.cpu().numpy() * 255).astype(np.uint8)
|
| 692 |
image_np = image_np[0]
|
| 693 |
final_image = Image.fromarray(image_np)
|
| 694 |
-
step_msg =
|
| 695 |
yield final_image, step_msg
|
| 696 |
|
| 697 |
|
|
@@ -710,10 +949,11 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
|
|
| 710 |
- Include style keywords like 'photorealistic', 'detailed', '8k'
|
| 711 |
- Choose **URL** mode for web links or **Plain Text** mode for VCARD, WiFi credentials, calendar events, etc.
|
| 712 |
- Try the examples below for inspiration
|
|
|
|
| 713 |
|
| 714 |
### Two Modes:
|
| 715 |
-
- **Standard QR**: Stable, accurate QR code generation (faster, more scannable)
|
| 716 |
-
- **Artistic QR**: More artistic and creative results with upscaling (slower, more creative)
|
| 717 |
|
| 718 |
### Note:
|
| 719 |
Feel free to share your suggestions or feedback on how to improve the app! Thanks!
|
|
@@ -747,7 +987,26 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
|
|
| 747 |
lines=3
|
| 748 |
)
|
| 749 |
|
| 750 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 751 |
# Add image size slider
|
| 752 |
image_size = gr.Slider(
|
| 753 |
minimum=512,
|
|
@@ -828,6 +1087,13 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
|
|
| 828 |
info="Enable upscaling with RealESRGAN for higher quality output (disabled by default for standard pipeline)"
|
| 829 |
)
|
| 830 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 831 |
# Add seed controls
|
| 832 |
use_custom_seed = gr.Checkbox(
|
| 833 |
label="Use Custom Seed",
|
|
@@ -840,6 +1106,7 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
|
|
| 840 |
step=1,
|
| 841 |
value=718313,
|
| 842 |
label="Seed",
|
|
|
|
| 843 |
info="Seed value for reproducibility. Same seed with same settings will produce the same result."
|
| 844 |
)
|
| 845 |
|
|
@@ -854,12 +1121,55 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
|
|
| 854 |
interactive=False,
|
| 855 |
lines=3,
|
| 856 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 857 |
|
| 858 |
# When clicking the button, it will trigger the main function
|
| 859 |
generate_btn.click(
|
| 860 |
fn=generate_standard_qr,
|
| 861 |
-
inputs=[prompt_input, text_input, input_type, image_size, border_size, error_correction, module_size, module_drawer, use_custom_seed, seed, enable_upscale],
|
| 862 |
-
outputs=[output_image, error_message]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 863 |
)
|
| 864 |
|
| 865 |
# Add examples
|
|
@@ -1009,7 +1319,26 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
|
|
| 1009 |
lines=3
|
| 1010 |
)
|
| 1011 |
|
| 1012 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1013 |
# Add image size slider for artistic QR
|
| 1014 |
artistic_image_size = gr.Slider(
|
| 1015 |
minimum=512,
|
|
@@ -1102,11 +1431,17 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
|
|
| 1102 |
step=1,
|
| 1103 |
value=718313,
|
| 1104 |
label="Seed",
|
|
|
|
| 1105 |
info="Seed value for reproducibility. Same seed with same settings will produce the same result."
|
| 1106 |
)
|
| 1107 |
|
| 1108 |
# FreeU Parameters
|
| 1109 |
gr.Markdown("### FreeU Quality Enhancement")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1110 |
freeu_b1 = gr.Slider(
|
| 1111 |
minimum=1.0,
|
| 1112 |
maximum=1.6,
|
|
@@ -1159,9 +1494,9 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
|
|
| 1159 |
minimum=0.0,
|
| 1160 |
maximum=5.0,
|
| 1161 |
step=0.1,
|
| 1162 |
-
value=
|
| 1163 |
label="SAG Blur Sigma",
|
| 1164 |
-
info="Blur amount for artistic blending. Higher values create softer, more artistic effects. Range: 0.0-5.0, Default:
|
| 1165 |
)
|
| 1166 |
|
| 1167 |
# The generate button for artistic QR
|
|
@@ -1175,74 +1510,124 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
|
|
| 1175 |
interactive=False,
|
| 1176 |
lines=3,
|
| 1177 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1178 |
|
| 1179 |
# When clicking the button, it will trigger the artistic function
|
| 1180 |
artistic_generate_btn.click(
|
| 1181 |
fn=generate_artistic_qr,
|
| 1182 |
-
inputs=[artistic_prompt_input, artistic_text_input, artistic_input_type, artistic_image_size, artistic_border_size, artistic_error_correction, artistic_module_size, artistic_module_drawer, artistic_use_custom_seed, artistic_seed, artistic_enable_upscale, freeu_b1, freeu_b2, freeu_s1, freeu_s2, enable_sag, sag_scale, sag_blur_sigma],
|
| 1183 |
-
outputs=[artistic_output_image, artistic_error_message]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1184 |
)
|
| 1185 |
|
| 1186 |
# Add examples for artistic QR
|
| 1187 |
artistic_examples = [
|
| 1188 |
[
|
| 1189 |
-
"some clothes spread on ropes, realistic, great details, out in the open air sunny day realistic, great details, absence of people, Detailed and Intricate, CGI, Photoshoot, rim light, 8k, 16k, ultra detail",
|
| 1190 |
"https://www.google.com",
|
| 1191 |
"URL",
|
| 1192 |
-
|
| 1193 |
-
|
| 1194 |
-
"Medium (15%)",
|
| 1195 |
-
|
| 1196 |
"Square"
|
| 1197 |
],
|
| 1198 |
[
|
| 1199 |
"some cards on poker tale, realistic, great details, realistic, great details,absence of people, Detailed and Intricate, CGI, Photoshoot,rim light, 8k, 16k, ultra detail",
|
| 1200 |
"https://store.steampowered.com",
|
| 1201 |
"URL",
|
| 1202 |
-
|
| 1203 |
-
|
| 1204 |
-
"
|
| 1205 |
-
|
| 1206 |
"Square"
|
| 1207 |
],
|
| 1208 |
[
|
| 1209 |
"a beautiful sunset over mountains, photorealistic, detailed landscape, golden hour, dramatic lighting, 8k, ultra detailed",
|
| 1210 |
"https://github.com",
|
| 1211 |
"URL",
|
| 1212 |
-
|
| 1213 |
-
|
| 1214 |
-
"
|
| 1215 |
-
|
| 1216 |
"Square"
|
| 1217 |
],
|
| 1218 |
[
|
| 1219 |
"underwater scene with coral reef and tropical fish, photorealistic, detailed, crystal clear water, sunlight rays, 8k, ultra detailed",
|
| 1220 |
"https://twitter.com",
|
| 1221 |
"URL",
|
| 1222 |
-
|
| 1223 |
-
|
| 1224 |
-
"
|
| 1225 |
-
|
| 1226 |
"Square"
|
| 1227 |
],
|
| 1228 |
[
|
| 1229 |
"futuristic cityscape with flying cars and neon lights, cyberpunk style, detailed architecture, night scene, 8k, ultra detailed",
|
| 1230 |
"https://linkedin.com",
|
| 1231 |
"URL",
|
| 1232 |
-
|
| 1233 |
-
|
| 1234 |
-
"
|
| 1235 |
-
|
| 1236 |
"Square"
|
| 1237 |
],
|
| 1238 |
[
|
| 1239 |
"vintage camera on wooden table, photorealistic, detailed textures, soft lighting, bokeh background, 8k, ultra detailed",
|
| 1240 |
"https://instagram.com",
|
| 1241 |
"URL",
|
| 1242 |
-
|
| 1243 |
-
|
| 1244 |
-
"
|
| 1245 |
-
|
| 1246 |
"Square"
|
| 1247 |
],
|
| 1248 |
[
|
|
@@ -1301,7 +1686,7 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
|
|
| 1301 |
],
|
| 1302 |
outputs=[artistic_output_image, artistic_error_message],
|
| 1303 |
fn=generate_artistic_qr,
|
| 1304 |
-
cache_examples=
|
| 1305 |
)
|
| 1306 |
|
| 1307 |
app.launch(share=False, mcp_server=True)
|
|
|
|
| 22 |
hf_hub_download(repo_id="Lykon/dreamshaper-7", filename="vae/diffusion_pytorch_model.fp16.safetensors", local_dir="models")
|
| 23 |
hf_hub_download(repo_id="stabilityai/sd-vae-ft-mse-original", filename="vae-ft-mse-840000-ema-pruned.safetensors", local_dir="models/vae")
|
| 24 |
hf_hub_download(repo_id="lllyasviel/Annotators", filename="RealESRGAN_x4plus.pth", local_dir="models/upscale_models")
|
|
|
|
| 25 |
|
| 26 |
def get_value_at_index(obj: Union[Sequence, Mapping], index: int) -> Any:
|
| 27 |
"""Returns the value at the given index of a sequence or mapping.
|
|
|
|
| 194 |
else: # artistic
|
| 195 |
yield from _pipeline_artistic(prompt, qr_text, input_type, image_size, border_size, error_correction, module_size, module_drawer, actual_seed, enable_upscale, freeu_b1, freeu_b2, freeu_s1, freeu_s2, enable_sag, sag_scale, sag_blur_sigma, controlnet_strength_first, controlnet_strength_final)
|
| 196 |
|
| 197 |
+
def generate_standard_qr(prompt: str, text_input: str, input_type: str = "URL", image_size: int = 512, border_size: int = 4, error_correction: str = "Medium (15%)", module_size: int = 12, module_drawer: str = "Square", use_custom_seed: bool = False, seed: int = 0, enable_upscale: bool = False, enable_freeu: bool = False):
|
| 198 |
"""Wrapper function for standard QR generation"""
|
| 199 |
+
# Get actual seed used (custom or random)
|
| 200 |
+
actual_seed = seed if use_custom_seed else random.randint(1, 2**64)
|
| 201 |
+
|
| 202 |
+
# Create settings JSON once
|
| 203 |
+
settings_dict = {
|
| 204 |
+
"pipeline": "standard",
|
| 205 |
+
"prompt": prompt,
|
| 206 |
+
"text_input": text_input,
|
| 207 |
+
"input_type": input_type,
|
| 208 |
+
"image_size": image_size,
|
| 209 |
+
"border_size": border_size,
|
| 210 |
+
"error_correction": error_correction,
|
| 211 |
+
"module_size": module_size,
|
| 212 |
+
"module_drawer": module_drawer,
|
| 213 |
+
"seed": actual_seed,
|
| 214 |
+
"use_custom_seed": True,
|
| 215 |
+
"enable_upscale": enable_upscale,
|
| 216 |
+
"enable_freeu": enable_freeu
|
| 217 |
+
}
|
| 218 |
+
settings_json = generate_settings_json(settings_dict)
|
| 219 |
+
|
| 220 |
+
# Generate QR and yield progressive results
|
| 221 |
+
generator = generate_qr_code_unified(prompt, text_input, input_type, image_size, border_size, error_correction, module_size, module_drawer, use_custom_seed, seed, pipeline="standard", enable_upscale=enable_upscale)
|
| 222 |
+
|
| 223 |
+
final_image = None
|
| 224 |
+
final_status = None
|
| 225 |
+
|
| 226 |
+
for image, status in generator:
|
| 227 |
+
final_image = image
|
| 228 |
+
final_status = status
|
| 229 |
+
# Show progressive updates but don't show accordion yet
|
| 230 |
+
yield (image, status, gr.update(), gr.update())
|
| 231 |
+
|
| 232 |
+
# After all steps complete, show the accordion with JSON
|
| 233 |
+
if final_image is not None:
|
| 234 |
+
yield (
|
| 235 |
+
final_image,
|
| 236 |
+
final_status,
|
| 237 |
+
gr.update(value=settings_json), # Update textbox content
|
| 238 |
+
gr.update(visible=True) # Make accordion visible only at the end
|
| 239 |
+
)
|
| 240 |
|
| 241 |
+
def generate_artistic_qr(prompt: str, text_input: str, input_type: str = "URL", image_size: int = 512, border_size: int = 4, error_correction: str = "Medium (15%)", module_size: int = 12, module_drawer: str = "Square", use_custom_seed: bool = False, seed: int = 0, enable_upscale: bool = True, enable_freeu: bool = True, freeu_b1: float = 1.4, freeu_b2: float = 1.3, freeu_s1: float = 0.0, freeu_s2: float = 1.3, enable_sag: bool = True, sag_scale: float = 0.5, sag_blur_sigma: float = 0.5, controlnet_strength_first: float = 0.45, controlnet_strength_final: float = 0.7):
|
| 242 |
"""Wrapper function for artistic QR generation with FreeU and SAG parameters"""
|
| 243 |
+
# Get actual seed used (custom or random)
|
| 244 |
+
actual_seed = seed if use_custom_seed else random.randint(1, 2**64)
|
| 245 |
+
|
| 246 |
+
# Create settings JSON once
|
| 247 |
+
settings_dict = {
|
| 248 |
+
"pipeline": "artistic",
|
| 249 |
+
"prompt": prompt,
|
| 250 |
+
"text_input": text_input,
|
| 251 |
+
"input_type": input_type,
|
| 252 |
+
"image_size": image_size,
|
| 253 |
+
"border_size": border_size,
|
| 254 |
+
"error_correction": error_correction,
|
| 255 |
+
"module_size": module_size,
|
| 256 |
+
"module_drawer": module_drawer,
|
| 257 |
+
"seed": actual_seed,
|
| 258 |
+
"use_custom_seed": True,
|
| 259 |
+
"enable_upscale": enable_upscale,
|
| 260 |
+
"enable_freeu": enable_freeu,
|
| 261 |
+
"freeu_b1": freeu_b1,
|
| 262 |
+
"freeu_b2": freeu_b2,
|
| 263 |
+
"freeu_s1": freeu_s1,
|
| 264 |
+
"freeu_s2": freeu_s2,
|
| 265 |
+
"enable_sag": enable_sag,
|
| 266 |
+
"sag_scale": sag_scale,
|
| 267 |
+
"sag_blur_sigma": sag_blur_sigma
|
| 268 |
+
}
|
| 269 |
+
settings_json = generate_settings_json(settings_dict)
|
| 270 |
+
|
| 271 |
+
# Generate QR and yield progressive results
|
| 272 |
+
generator = generate_qr_code_unified(prompt, text_input, input_type, image_size, border_size, error_correction, module_size, module_drawer, use_custom_seed, seed, pipeline="artistic", enable_upscale=enable_upscale, freeu_b1=freeu_b1, freeu_b2=freeu_b2, freeu_s1=freeu_s1, freeu_s2=freeu_s2, enable_sag=enable_sag, sag_scale=sag_scale, sag_blur_sigma=sag_blur_sigma, controlnet_strength_first=controlnet_strength_first, controlnet_strength_final=controlnet_strength_final)
|
| 273 |
+
|
| 274 |
+
final_image = None
|
| 275 |
+
final_status = None
|
| 276 |
+
|
| 277 |
+
for image, status in generator:
|
| 278 |
+
final_image = image
|
| 279 |
+
final_status = status
|
| 280 |
+
# Show progressive updates but don't show accordion yet
|
| 281 |
+
yield (image, status, gr.update(), gr.update())
|
| 282 |
+
|
| 283 |
+
# After all steps complete, show the accordion with JSON
|
| 284 |
+
if final_image is not None:
|
| 285 |
+
yield (
|
| 286 |
+
final_image,
|
| 287 |
+
final_status,
|
| 288 |
+
gr.update(value=settings_json), # Update textbox content
|
| 289 |
+
gr.update(visible=True) # Make accordion visible only at the end
|
| 290 |
+
)
|
| 291 |
+
|
| 292 |
+
# Helper functions for shareable settings JSON
|
| 293 |
+
import json
|
| 294 |
+
|
| 295 |
+
def generate_settings_json(params_dict: dict) -> str:
|
| 296 |
+
"""Generate a formatted JSON string from parameters dictionary"""
|
| 297 |
+
try:
|
| 298 |
+
return json.dumps(params_dict, indent=2, ensure_ascii=False)
|
| 299 |
+
except Exception as e:
|
| 300 |
+
return json.dumps({"error": f"Failed to generate JSON: {str(e)}"}, indent=2)
|
| 301 |
+
|
| 302 |
+
def parse_settings_json(json_string: str) -> dict:
|
| 303 |
+
"""Parse JSON string and return parameters dictionary with validation"""
|
| 304 |
+
try:
|
| 305 |
+
if not json_string or not json_string.strip():
|
| 306 |
+
return {}
|
| 307 |
+
|
| 308 |
+
params = json.loads(json_string)
|
| 309 |
+
if not isinstance(params, dict):
|
| 310 |
+
return {}
|
| 311 |
+
|
| 312 |
+
return params
|
| 313 |
+
except json.JSONDecodeError as e:
|
| 314 |
+
return {"error": f"Invalid JSON: {str(e)}"}
|
| 315 |
+
except Exception as e:
|
| 316 |
+
return {"error": f"Failed to parse JSON: {str(e)}"}
|
| 317 |
+
|
| 318 |
+
def load_settings_from_json_standard(json_string: str):
|
| 319 |
+
"""Load settings from JSON for Standard pipeline"""
|
| 320 |
+
try:
|
| 321 |
+
params = json.loads(json_string)
|
| 322 |
+
|
| 323 |
+
# Validate pipeline type
|
| 324 |
+
pipeline = params.get("pipeline", "standard") # Default to standard for backward compatibility
|
| 325 |
+
if pipeline != "standard":
|
| 326 |
+
error_msg = f"❌ Error: You're trying to load {pipeline.upper()} pipeline settings into the STANDARD pipeline. Please use the correct tab."
|
| 327 |
+
# Return empty updates for all fields + error message + make status visible
|
| 328 |
+
return (
|
| 329 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 330 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 331 |
+
gr.update(), gr.update(),
|
| 332 |
+
gr.update(value=error_msg, visible=True)
|
| 333 |
+
)
|
| 334 |
+
|
| 335 |
+
# Extract parameters with defaults
|
| 336 |
+
prompt = params.get("prompt", "")
|
| 337 |
+
text_input = params.get("text_input", "")
|
| 338 |
+
input_type = params.get("input_type", "URL")
|
| 339 |
+
image_size = params.get("image_size", 512)
|
| 340 |
+
border_size = params.get("border_size", 4)
|
| 341 |
+
error_correction = params.get("error_correction", "Medium (15%)")
|
| 342 |
+
module_size = params.get("module_size", 12)
|
| 343 |
+
module_drawer = params.get("module_drawer", "Square")
|
| 344 |
+
use_custom_seed = params.get("use_custom_seed", True)
|
| 345 |
+
seed = params.get("seed", 718313)
|
| 346 |
+
enable_upscale = params.get("enable_upscale", False)
|
| 347 |
+
enable_freeu = params.get("enable_freeu", False)
|
| 348 |
+
|
| 349 |
+
success_msg = "✅ Settings loaded successfully!"
|
| 350 |
+
return (
|
| 351 |
+
prompt, text_input, input_type, image_size, border_size,
|
| 352 |
+
error_correction, module_size, module_drawer, use_custom_seed,
|
| 353 |
+
seed, enable_upscale, enable_freeu,
|
| 354 |
+
gr.update(value=success_msg, visible=True)
|
| 355 |
+
)
|
| 356 |
+
|
| 357 |
+
except json.JSONDecodeError as e:
|
| 358 |
+
error_msg = f"❌ Invalid JSON format: {str(e)}"
|
| 359 |
+
return (
|
| 360 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 361 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 362 |
+
gr.update(), gr.update(),
|
| 363 |
+
gr.update(value=error_msg, visible=True)
|
| 364 |
+
)
|
| 365 |
+
except Exception as e:
|
| 366 |
+
error_msg = f"❌ Error loading settings: {str(e)}"
|
| 367 |
+
return (
|
| 368 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 369 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 370 |
+
gr.update(), gr.update(),
|
| 371 |
+
gr.update(value=error_msg, visible=True)
|
| 372 |
+
)
|
| 373 |
+
|
| 374 |
+
def load_settings_from_json_artistic(json_string: str):
|
| 375 |
+
"""Load settings from JSON for Artistic pipeline"""
|
| 376 |
+
try:
|
| 377 |
+
params = json.loads(json_string)
|
| 378 |
+
|
| 379 |
+
# Validate pipeline type
|
| 380 |
+
pipeline = params.get("pipeline", "artistic") # Default to artistic for backward compatibility
|
| 381 |
+
if pipeline != "artistic":
|
| 382 |
+
error_msg = f"❌ Error: You're trying to load {pipeline.upper()} pipeline settings into the ARTISTIC pipeline. Please use the correct tab."
|
| 383 |
+
# Return empty updates for all fields + error message + make status visible
|
| 384 |
+
return (
|
| 385 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 386 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 387 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 388 |
+
gr.update(), gr.update(), gr.update(), gr.update(),
|
| 389 |
+
gr.update(value=error_msg, visible=True)
|
| 390 |
+
)
|
| 391 |
+
|
| 392 |
+
# Extract parameters with defaults
|
| 393 |
+
prompt = params.get("prompt", "")
|
| 394 |
+
text_input = params.get("text_input", "")
|
| 395 |
+
input_type = params.get("input_type", "URL")
|
| 396 |
+
image_size = params.get("image_size", 704)
|
| 397 |
+
border_size = params.get("border_size", 6)
|
| 398 |
+
error_correction = params.get("error_correction", "High (30%)")
|
| 399 |
+
module_size = params.get("module_size", 16)
|
| 400 |
+
module_drawer = params.get("module_drawer", "Square")
|
| 401 |
+
use_custom_seed = params.get("use_custom_seed", True)
|
| 402 |
+
seed = params.get("seed", 718313)
|
| 403 |
+
enable_upscale = params.get("enable_upscale", True)
|
| 404 |
+
enable_freeu = params.get("enable_freeu", True)
|
| 405 |
+
freeu_b1 = params.get("freeu_b1", 1.4)
|
| 406 |
+
freeu_b2 = params.get("freeu_b2", 1.3)
|
| 407 |
+
freeu_s1 = params.get("freeu_s1", 0.0)
|
| 408 |
+
freeu_s2 = params.get("freeu_s2", 1.3)
|
| 409 |
+
enable_sag = params.get("enable_sag", True)
|
| 410 |
+
sag_scale = params.get("sag_scale", 0.5)
|
| 411 |
+
sag_blur_sigma = params.get("sag_blur_sigma", 0.5)
|
| 412 |
+
|
| 413 |
+
success_msg = "✅ Settings loaded successfully!"
|
| 414 |
+
return (
|
| 415 |
+
prompt, text_input, input_type, image_size, border_size,
|
| 416 |
+
error_correction, module_size, module_drawer, use_custom_seed,
|
| 417 |
+
seed, enable_upscale, enable_freeu, freeu_b1, freeu_b2, freeu_s1,
|
| 418 |
+
freeu_s2, enable_sag, sag_scale, sag_blur_sigma,
|
| 419 |
+
gr.update(value=success_msg, visible=True)
|
| 420 |
+
)
|
| 421 |
+
|
| 422 |
+
except json.JSONDecodeError as e:
|
| 423 |
+
error_msg = f"❌ Invalid JSON format: {str(e)}"
|
| 424 |
+
return (
|
| 425 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 426 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 427 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 428 |
+
gr.update(), gr.update(), gr.update(), gr.update(),
|
| 429 |
+
gr.update(value=error_msg, visible=True)
|
| 430 |
+
)
|
| 431 |
+
except Exception as e:
|
| 432 |
+
error_msg = f"❌ Error loading settings: {str(e)}"
|
| 433 |
+
return (
|
| 434 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 435 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 436 |
+
gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
|
| 437 |
+
gr.update(), gr.update(), gr.update(), gr.update(),
|
| 438 |
+
gr.update(value=error_msg, visible=True)
|
| 439 |
+
)
|
| 440 |
|
| 441 |
def add_noise_to_border_only(image_tensor, seed: int, border_size: int, image_size: int, module_size: int = 12):
|
| 442 |
"""
|
|
|
|
| 566 |
except RuntimeError as e:
|
| 567 |
error_msg = (
|
| 568 |
f"Error generating QR code: {str(e)}\n"
|
| 569 |
+
"Try with a shorter text, increase the image size, or decrease the border size, module size, and error correction level under Change Settings Manually."
|
| 570 |
)
|
| 571 |
yield None, error_msg
|
| 572 |
return
|
|
|
|
| 688 |
image_np = (image_tensor.cpu().numpy() * 255).astype(np.uint8)
|
| 689 |
image_np = image_np[0]
|
| 690 |
pil_image = Image.fromarray(image_np)
|
| 691 |
+
yield pil_image, "No errors, all good! Final QR art generated and upscaled. (step 4/4)"
|
| 692 |
else:
|
| 693 |
# No upscaling
|
| 694 |
image_tensor = get_value_at_index(vaedecode_21, 0)
|
| 695 |
image_np = (image_tensor.cpu().numpy() * 255).astype(np.uint8)
|
| 696 |
image_np = image_np[0]
|
| 697 |
pil_image = Image.fromarray(image_np)
|
| 698 |
+
yield pil_image, "No errors, all good! Final QR art generated."
|
| 699 |
|
| 700 |
+
def _pipeline_artistic(prompt: str, qr_text: str, input_type: str, image_size: int, border_size: int, error_correction: str, module_size: int, module_drawer: str, seed: int, enable_upscale: bool = True, freeu_b1: float = 1.4, freeu_b2: float = 1.3, freeu_s1: float = 0.0, freeu_s2: float = 1.3, enable_sag: bool = True, sag_scale: float = 0.5, sag_blur_sigma: float = 0.5, controlnet_strength_first: float = 0.45, controlnet_strength_final: float = 0.7):
|
| 701 |
# Generate QR code
|
| 702 |
qr_protocol = "None" if input_type == "Plain Text" else "Https"
|
| 703 |
|
|
|
|
| 716 |
except RuntimeError as e:
|
| 717 |
error_msg = (
|
| 718 |
f"Error generating QR code: {str(e)}\n"
|
| 719 |
+
"Try with a shorter text, increase the image size, or decrease the border size, module size, and error correction level under Change Settings Manually."
|
| 720 |
)
|
| 721 |
yield None, error_msg
|
| 722 |
return
|
|
|
|
| 855 |
first_pass_np = (first_pass_tensor.cpu().numpy() * 255).astype(np.uint8)
|
| 856 |
first_pass_np = first_pass_np[0]
|
| 857 |
first_pass_pil = Image.fromarray(first_pass_np)
|
| 858 |
+
# Calculate step based on border and upscale
|
| 859 |
+
if enable_upscale:
|
| 860 |
+
step_msg = "First enhancement pass complete (step 3/5)... final refinement pass" if border_size > 0 else "First enhancement pass complete (step 2/4)... final refinement pass"
|
| 861 |
+
else:
|
| 862 |
+
step_msg = "First enhancement pass complete (step 3/4)... final refinement pass" if border_size > 0 else "First enhancement pass complete (step 2/3)... final refinement pass"
|
| 863 |
yield first_pass_pil, step_msg
|
| 864 |
|
| 865 |
# Final ControlNet pass (second pass - refinement)
|
|
|
|
| 922 |
image_np = (image_tensor.cpu().numpy() * 255).astype(np.uint8)
|
| 923 |
image_np = image_np[0]
|
| 924 |
final_image = Image.fromarray(image_np)
|
| 925 |
+
step_msg = "No errors, all good! Final artistic QR code generated and upscaled. (step 5/5)" if border_size > 0 else "No errors, all good! Final artistic QR code generated and upscaled. (step 4/4)"
|
| 926 |
yield final_image, step_msg
|
| 927 |
else:
|
| 928 |
# No upscaling
|
|
|
|
| 930 |
image_np = (image_tensor.cpu().numpy() * 255).astype(np.uint8)
|
| 931 |
image_np = image_np[0]
|
| 932 |
final_image = Image.fromarray(image_np)
|
| 933 |
+
step_msg = "No errors, all good! Final artistic QR code generated. (step 4/4)" if border_size > 0 else "No errors, all good! Final artistic QR code generated. (step 3/3)"
|
| 934 |
yield final_image, step_msg
|
| 935 |
|
| 936 |
|
|
|
|
| 949 |
- Include style keywords like 'photorealistic', 'detailed', '8k'
|
| 950 |
- Choose **URL** mode for web links or **Plain Text** mode for VCARD, WiFi credentials, calendar events, etc.
|
| 951 |
- Try the examples below for inspiration
|
| 952 |
+
- **Copy/paste settings**: After generation, copy the JSON settings string that appears below the image and paste it into "Import Settings from JSON" to reproduce exact results or share with others
|
| 953 |
|
| 954 |
### Two Modes:
|
| 955 |
+
- **Standard QR**: Stable, accurate QR code generation (faster, more scannable, less creative)
|
| 956 |
+
- **Artistic QR**: More artistic and creative results with upscaling (slower, more creative, less scannable)
|
| 957 |
|
| 958 |
### Note:
|
| 959 |
Feel free to share your suggestions or feedback on how to improve the app! Thanks!
|
|
|
|
| 987 |
lines=3
|
| 988 |
)
|
| 989 |
|
| 990 |
+
# Import Settings section - separate accordion
|
| 991 |
+
with gr.Accordion("Import Settings from JSON", open=False):
|
| 992 |
+
gr.Markdown("Paste a settings JSON string (copied from a previous generation) to load all parameters at once.")
|
| 993 |
+
import_json_input_standard = gr.Textbox(
|
| 994 |
+
label="Paste Settings JSON",
|
| 995 |
+
placeholder='{"pipeline": "standard", "prompt": "...", "seed": 718313, ...}',
|
| 996 |
+
lines=3
|
| 997 |
+
)
|
| 998 |
+
import_status_standard = gr.Textbox(
|
| 999 |
+
label="Import Status",
|
| 1000 |
+
interactive=False,
|
| 1001 |
+
visible=False,
|
| 1002 |
+
lines=2
|
| 1003 |
+
)
|
| 1004 |
+
with gr.Row():
|
| 1005 |
+
load_settings_btn_standard = gr.Button("Load Settings", variant="primary")
|
| 1006 |
+
clear_json_btn_standard = gr.Button("Clear", variant="secondary")
|
| 1007 |
+
|
| 1008 |
+
# Change Settings Manually - separate accordion
|
| 1009 |
+
with gr.Accordion("Change Settings Manually", open=False):
|
| 1010 |
# Add image size slider
|
| 1011 |
image_size = gr.Slider(
|
| 1012 |
minimum=512,
|
|
|
|
| 1087 |
info="Enable upscaling with RealESRGAN for higher quality output (disabled by default for standard pipeline)"
|
| 1088 |
)
|
| 1089 |
|
| 1090 |
+
# Add FreeU checkbox
|
| 1091 |
+
enable_freeu_standard = gr.Checkbox(
|
| 1092 |
+
label="Enable FreeU",
|
| 1093 |
+
value=False,
|
| 1094 |
+
info="Enable FreeU quality enhancement (disabled by default for standard pipeline)"
|
| 1095 |
+
)
|
| 1096 |
+
|
| 1097 |
# Add seed controls
|
| 1098 |
use_custom_seed = gr.Checkbox(
|
| 1099 |
label="Use Custom Seed",
|
|
|
|
| 1106 |
step=1,
|
| 1107 |
value=718313,
|
| 1108 |
label="Seed",
|
| 1109 |
+
visible=True, # Initially visible since use_custom_seed=True
|
| 1110 |
info="Seed value for reproducibility. Same seed with same settings will produce the same result."
|
| 1111 |
)
|
| 1112 |
|
|
|
|
| 1121 |
interactive=False,
|
| 1122 |
lines=3,
|
| 1123 |
)
|
| 1124 |
+
# Wrap settings output in accordion (initially hidden)
|
| 1125 |
+
with gr.Accordion("Shareable Settings (JSON)", open=True, visible=False) as settings_accordion_standard:
|
| 1126 |
+
settings_output_standard = gr.Textbox(
|
| 1127 |
+
label="Copy this JSON to share your exact settings",
|
| 1128 |
+
interactive=True,
|
| 1129 |
+
lines=5,
|
| 1130 |
+
show_copy_button=True
|
| 1131 |
+
)
|
| 1132 |
|
| 1133 |
# When clicking the button, it will trigger the main function
|
| 1134 |
generate_btn.click(
|
| 1135 |
fn=generate_standard_qr,
|
| 1136 |
+
inputs=[prompt_input, text_input, input_type, image_size, border_size, error_correction, module_size, module_drawer, use_custom_seed, seed, enable_upscale, enable_freeu_standard],
|
| 1137 |
+
outputs=[output_image, error_message, settings_output_standard, settings_accordion_standard]
|
| 1138 |
+
)
|
| 1139 |
+
|
| 1140 |
+
# Load Settings button event handler
|
| 1141 |
+
load_settings_btn_standard.click(
|
| 1142 |
+
fn=load_settings_from_json_standard,
|
| 1143 |
+
inputs=[import_json_input_standard],
|
| 1144 |
+
outputs=[
|
| 1145 |
+
prompt_input,
|
| 1146 |
+
text_input,
|
| 1147 |
+
input_type,
|
| 1148 |
+
image_size,
|
| 1149 |
+
border_size,
|
| 1150 |
+
error_correction,
|
| 1151 |
+
module_size,
|
| 1152 |
+
module_drawer,
|
| 1153 |
+
use_custom_seed,
|
| 1154 |
+
seed,
|
| 1155 |
+
enable_upscale,
|
| 1156 |
+
enable_freeu_standard,
|
| 1157 |
+
import_status_standard
|
| 1158 |
+
]
|
| 1159 |
+
)
|
| 1160 |
+
|
| 1161 |
+
# Clear button event handler
|
| 1162 |
+
clear_json_btn_standard.click(
|
| 1163 |
+
fn=lambda: ("", gr.update(visible=False)),
|
| 1164 |
+
inputs=[],
|
| 1165 |
+
outputs=[import_json_input_standard, import_status_standard]
|
| 1166 |
+
)
|
| 1167 |
+
|
| 1168 |
+
# Seed slider visibility toggle
|
| 1169 |
+
use_custom_seed.change(
|
| 1170 |
+
fn=lambda x: gr.update(visible=x),
|
| 1171 |
+
inputs=[use_custom_seed],
|
| 1172 |
+
outputs=[seed]
|
| 1173 |
)
|
| 1174 |
|
| 1175 |
# Add examples
|
|
|
|
| 1319 |
lines=3
|
| 1320 |
)
|
| 1321 |
|
| 1322 |
+
# Import Settings section - separate accordion
|
| 1323 |
+
with gr.Accordion("Import Settings from JSON", open=False):
|
| 1324 |
+
gr.Markdown("Paste a settings JSON string (copied from a previous generation) to load all parameters at once.")
|
| 1325 |
+
import_json_input_artistic = gr.Textbox(
|
| 1326 |
+
label="Paste Settings JSON",
|
| 1327 |
+
placeholder='{"pipeline": "artistic", "prompt": "...", "seed": 718313, ...}',
|
| 1328 |
+
lines=3
|
| 1329 |
+
)
|
| 1330 |
+
import_status_artistic = gr.Textbox(
|
| 1331 |
+
label="Import Status",
|
| 1332 |
+
interactive=False,
|
| 1333 |
+
visible=False,
|
| 1334 |
+
lines=2
|
| 1335 |
+
)
|
| 1336 |
+
with gr.Row():
|
| 1337 |
+
load_settings_btn_artistic = gr.Button("Load Settings", variant="primary")
|
| 1338 |
+
clear_json_btn_artistic = gr.Button("Clear", variant="secondary")
|
| 1339 |
+
|
| 1340 |
+
# Change Settings Manually - separate accordion
|
| 1341 |
+
with gr.Accordion("Change Settings Manually", open=False):
|
| 1342 |
# Add image size slider for artistic QR
|
| 1343 |
artistic_image_size = gr.Slider(
|
| 1344 |
minimum=512,
|
|
|
|
| 1431 |
step=1,
|
| 1432 |
value=718313,
|
| 1433 |
label="Seed",
|
| 1434 |
+
visible=True, # Initially visible since artistic_use_custom_seed=True
|
| 1435 |
info="Seed value for reproducibility. Same seed with same settings will produce the same result."
|
| 1436 |
)
|
| 1437 |
|
| 1438 |
# FreeU Parameters
|
| 1439 |
gr.Markdown("### FreeU Quality Enhancement")
|
| 1440 |
+
enable_freeu_artistic = gr.Checkbox(
|
| 1441 |
+
label="Enable FreeU",
|
| 1442 |
+
value=True,
|
| 1443 |
+
info="Enable FreeU quality enhancement (enabled by default for artistic pipeline)"
|
| 1444 |
+
)
|
| 1445 |
freeu_b1 = gr.Slider(
|
| 1446 |
minimum=1.0,
|
| 1447 |
maximum=1.6,
|
|
|
|
| 1494 |
minimum=0.0,
|
| 1495 |
maximum=5.0,
|
| 1496 |
step=0.1,
|
| 1497 |
+
value=0.5,
|
| 1498 |
label="SAG Blur Sigma",
|
| 1499 |
+
info="Blur amount for artistic blending. Higher values create softer, more artistic effects. Range: 0.0-5.0, Default: 0.5"
|
| 1500 |
)
|
| 1501 |
|
| 1502 |
# The generate button for artistic QR
|
|
|
|
| 1510 |
interactive=False,
|
| 1511 |
lines=3,
|
| 1512 |
)
|
| 1513 |
+
# Wrap settings output in accordion (initially hidden)
|
| 1514 |
+
with gr.Accordion("Shareable Settings (JSON)", open=True, visible=False) as settings_accordion_artistic:
|
| 1515 |
+
settings_output_artistic = gr.Textbox(
|
| 1516 |
+
label="Copy this JSON to share your exact settings",
|
| 1517 |
+
interactive=True,
|
| 1518 |
+
lines=5,
|
| 1519 |
+
show_copy_button=True
|
| 1520 |
+
)
|
| 1521 |
|
| 1522 |
# When clicking the button, it will trigger the artistic function
|
| 1523 |
artistic_generate_btn.click(
|
| 1524 |
fn=generate_artistic_qr,
|
| 1525 |
+
inputs=[artistic_prompt_input, artistic_text_input, artistic_input_type, artistic_image_size, artistic_border_size, artistic_error_correction, artistic_module_size, artistic_module_drawer, artistic_use_custom_seed, artistic_seed, artistic_enable_upscale, enable_freeu_artistic, freeu_b1, freeu_b2, freeu_s1, freeu_s2, enable_sag, sag_scale, sag_blur_sigma],
|
| 1526 |
+
outputs=[artistic_output_image, artistic_error_message, settings_output_artistic, settings_accordion_artistic]
|
| 1527 |
+
)
|
| 1528 |
+
|
| 1529 |
+
# Load Settings button event handler
|
| 1530 |
+
load_settings_btn_artistic.click(
|
| 1531 |
+
fn=load_settings_from_json_artistic,
|
| 1532 |
+
inputs=[import_json_input_artistic],
|
| 1533 |
+
outputs=[
|
| 1534 |
+
artistic_prompt_input,
|
| 1535 |
+
artistic_text_input,
|
| 1536 |
+
artistic_input_type,
|
| 1537 |
+
artistic_image_size,
|
| 1538 |
+
artistic_border_size,
|
| 1539 |
+
artistic_error_correction,
|
| 1540 |
+
artistic_module_size,
|
| 1541 |
+
artistic_module_drawer,
|
| 1542 |
+
artistic_use_custom_seed,
|
| 1543 |
+
artistic_seed,
|
| 1544 |
+
artistic_enable_upscale,
|
| 1545 |
+
enable_freeu_artistic,
|
| 1546 |
+
freeu_b1,
|
| 1547 |
+
freeu_b2,
|
| 1548 |
+
freeu_s1,
|
| 1549 |
+
freeu_s2,
|
| 1550 |
+
enable_sag,
|
| 1551 |
+
sag_scale,
|
| 1552 |
+
sag_blur_sigma,
|
| 1553 |
+
import_status_artistic
|
| 1554 |
+
]
|
| 1555 |
+
)
|
| 1556 |
+
|
| 1557 |
+
# Clear button event handler for artistic tab
|
| 1558 |
+
clear_json_btn_artistic.click(
|
| 1559 |
+
fn=lambda: ("", gr.update(visible=False)),
|
| 1560 |
+
inputs=[],
|
| 1561 |
+
outputs=[import_json_input_artistic, import_status_artistic]
|
| 1562 |
+
)
|
| 1563 |
+
|
| 1564 |
+
# Seed slider visibility toggle for artistic tab
|
| 1565 |
+
artistic_use_custom_seed.change(
|
| 1566 |
+
fn=lambda x: gr.update(visible=x),
|
| 1567 |
+
inputs=[artistic_use_custom_seed],
|
| 1568 |
+
outputs=[artistic_seed]
|
| 1569 |
)
|
| 1570 |
|
| 1571 |
# Add examples for artistic QR
|
| 1572 |
artistic_examples = [
|
| 1573 |
[
|
| 1574 |
+
"some clothes spread on ropes, Japanese girl sits inside in the middle of the image, few sakura flowers, realistic, great details, out in the open air sunny day realistic, great details, absence of people, Detailed and Intricate, CGI, Photoshoot, rim light, 8k, 16k, ultra detail",
|
| 1575 |
"https://www.google.com",
|
| 1576 |
"URL",
|
| 1577 |
+
640, # Image size
|
| 1578 |
+
6, # Border
|
| 1579 |
+
"Medium (15%)", # Error correction
|
| 1580 |
+
14, # Module size
|
| 1581 |
"Square"
|
| 1582 |
],
|
| 1583 |
[
|
| 1584 |
"some cards on poker tale, realistic, great details, realistic, great details,absence of people, Detailed and Intricate, CGI, Photoshoot,rim light, 8k, 16k, ultra detail",
|
| 1585 |
"https://store.steampowered.com",
|
| 1586 |
"URL",
|
| 1587 |
+
768, # Image size
|
| 1588 |
+
6, # Border
|
| 1589 |
+
"High (30%)", # Error correction
|
| 1590 |
+
16, # Module size
|
| 1591 |
"Square"
|
| 1592 |
],
|
| 1593 |
[
|
| 1594 |
"a beautiful sunset over mountains, photorealistic, detailed landscape, golden hour, dramatic lighting, 8k, ultra detailed",
|
| 1595 |
"https://github.com",
|
| 1596 |
"URL",
|
| 1597 |
+
704, # Image size (default)
|
| 1598 |
+
6, # Border
|
| 1599 |
+
"High (30%)", # Error correction
|
| 1600 |
+
16, # Module size
|
| 1601 |
"Square"
|
| 1602 |
],
|
| 1603 |
[
|
| 1604 |
"underwater scene with coral reef and tropical fish, photorealistic, detailed, crystal clear water, sunlight rays, 8k, ultra detailed",
|
| 1605 |
"https://twitter.com",
|
| 1606 |
"URL",
|
| 1607 |
+
704, # Image size (default)
|
| 1608 |
+
6, # Border
|
| 1609 |
+
"High (30%)", # Error correction
|
| 1610 |
+
16, # Module size
|
| 1611 |
"Square"
|
| 1612 |
],
|
| 1613 |
[
|
| 1614 |
"futuristic cityscape with flying cars and neon lights, cyberpunk style, detailed architecture, night scene, 8k, ultra detailed",
|
| 1615 |
"https://linkedin.com",
|
| 1616 |
"URL",
|
| 1617 |
+
704, # Image size (default)
|
| 1618 |
+
6, # Border
|
| 1619 |
+
"High (30%)", # Error correction
|
| 1620 |
+
16, # Module size
|
| 1621 |
"Square"
|
| 1622 |
],
|
| 1623 |
[
|
| 1624 |
"vintage camera on wooden table, photorealistic, detailed textures, soft lighting, bokeh background, 8k, ultra detailed",
|
| 1625 |
"https://instagram.com",
|
| 1626 |
"URL",
|
| 1627 |
+
704, # Image size (default)
|
| 1628 |
+
6, # Border
|
| 1629 |
+
"High (30%)", # Error correction
|
| 1630 |
+
16, # Module size
|
| 1631 |
"Square"
|
| 1632 |
],
|
| 1633 |
[
|
|
|
|
| 1686 |
],
|
| 1687 |
outputs=[artistic_output_image, artistic_error_message],
|
| 1688 |
fn=generate_artistic_qr,
|
| 1689 |
+
cache_examples=True
|
| 1690 |
)
|
| 1691 |
|
| 1692 |
app.launch(share=False, mcp_server=True)
|