Oysiyl commited on
Commit
b738f5e
·
1 Parent(s): 2d60615

fix bug with wrong counter on steps; controlnet sliders, updating examples for artistic pipeline

Browse files
Files changed (1) hide show
  1. app.py +144 -66
app.py CHANGED
@@ -239,7 +239,7 @@ valid_models = [
239
  model_management.load_models_gpu(valid_models)
240
 
241
  @spaces.GPU(duration=30)
242
- def generate_qr_code_unified(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, pipeline: str = "standard", enable_upscale: bool = False, 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 = 1.5, controlnet_strength_first: float = 0.45, controlnet_strength_final: float = 0.7):
243
  # Only manipulate the text if it's a URL input type
244
  qr_text = text_input
245
  if input_type == "URL":
@@ -253,11 +253,11 @@ def generate_qr_code_unified(prompt: str, text_input: str, input_type: str = "UR
253
 
254
  with torch.inference_mode():
255
  if pipeline == "standard":
256
- yield from _pipeline_standard(prompt, qr_text, input_type, image_size, border_size, error_correction, module_size, module_drawer, actual_seed, enable_upscale)
257
  else: # artistic
258
  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)
259
 
260
- 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):
261
  """Wrapper function for standard QR generation"""
262
  # Get actual seed used (custom or random)
263
  actual_seed = seed if use_custom_seed else random.randint(1, 2**64)
@@ -276,12 +276,14 @@ def generate_standard_qr(prompt: str, text_input: str, input_type: str = "URL",
276
  "seed": actual_seed,
277
  "use_custom_seed": True,
278
  "enable_upscale": enable_upscale,
279
- "enable_freeu": enable_freeu
 
 
280
  }
281
  settings_json = generate_settings_json(settings_dict)
282
 
283
  # Generate QR and yield progressive results
284
- 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)
285
 
286
  final_image = None
287
  final_status = None
@@ -301,7 +303,7 @@ def generate_standard_qr(prompt: str, text_input: str, input_type: str = "URL",
301
  gr.update(visible=True) # Make accordion visible only at the end
302
  )
303
 
304
- 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):
305
  """Wrapper function for artistic QR generation with FreeU and SAG parameters"""
306
  # Get actual seed used (custom or random)
307
  actual_seed = seed if use_custom_seed else random.randint(1, 2**64)
@@ -327,7 +329,9 @@ def generate_artistic_qr(prompt: str, text_input: str, input_type: str = "URL",
327
  "freeu_s2": freeu_s2,
328
  "enable_sag": enable_sag,
329
  "sag_scale": sag_scale,
330
- "sag_blur_sigma": sag_blur_sigma
 
 
331
  }
332
  settings_json = generate_settings_json(settings_dict)
333
 
@@ -391,7 +395,7 @@ def load_settings_from_json_standard(json_string: str):
391
  return (
392
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
393
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
394
- gr.update(), gr.update(),
395
  gr.update(value=error_msg, visible=True)
396
  )
397
 
@@ -408,13 +412,15 @@ def load_settings_from_json_standard(json_string: str):
408
  seed = params.get("seed", 718313)
409
  enable_upscale = params.get("enable_upscale", False)
410
  enable_freeu = params.get("enable_freeu", False)
 
 
411
 
412
  success_msg = "✅ Settings loaded successfully!"
413
  return (
414
  prompt, text_input, input_type, image_size, border_size,
415
  error_correction, module_size, module_drawer, use_custom_seed,
416
- seed, enable_upscale, enable_freeu,
417
- gr.update(value=success_msg, visible=True)
418
  )
419
 
420
  except json.JSONDecodeError as e:
@@ -422,7 +428,7 @@ def load_settings_from_json_standard(json_string: str):
422
  return (
423
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
424
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
425
- gr.update(), gr.update(),
426
  gr.update(value=error_msg, visible=True)
427
  )
428
  except Exception as e:
@@ -430,7 +436,7 @@ def load_settings_from_json_standard(json_string: str):
430
  return (
431
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
432
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
433
- gr.update(), gr.update(),
434
  gr.update(value=error_msg, visible=True)
435
  )
436
 
@@ -448,8 +454,8 @@ def load_settings_from_json_artistic(json_string: str):
448
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
449
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
450
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
451
- gr.update(), gr.update(), gr.update(), gr.update(),
452
- gr.update(value=error_msg, visible=True)
453
  )
454
 
455
  # Extract parameters with defaults
@@ -472,14 +478,16 @@ def load_settings_from_json_artistic(json_string: str):
472
  enable_sag = params.get("enable_sag", True)
473
  sag_scale = params.get("sag_scale", 0.5)
474
  sag_blur_sigma = params.get("sag_blur_sigma", 0.5)
 
 
475
 
476
  success_msg = "✅ Settings loaded successfully!"
477
  return (
478
  prompt, text_input, input_type, image_size, border_size,
479
  error_correction, module_size, module_drawer, use_custom_seed,
480
  seed, enable_upscale, enable_freeu, freeu_b1, freeu_b2, freeu_s1,
481
- freeu_s2, enable_sag, sag_scale, sag_blur_sigma,
482
- gr.update(value=success_msg, visible=True)
483
  )
484
 
485
  except json.JSONDecodeError as e:
@@ -488,8 +496,8 @@ def load_settings_from_json_artistic(json_string: str):
488
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
489
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
490
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
491
- gr.update(), gr.update(), gr.update(), gr.update(),
492
- gr.update(value=error_msg, visible=True)
493
  )
494
  except Exception as e:
495
  error_msg = f"❌ Error loading settings: {str(e)}"
@@ -497,8 +505,8 @@ def load_settings_from_json_artistic(json_string: str):
497
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
498
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
499
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
500
- gr.update(), gr.update(), gr.update(), gr.update(),
501
- gr.update(value=error_msg, visible=True)
502
  )
503
 
504
  def add_noise_to_border_only(image_tensor, seed: int, border_size: int, image_size: int, module_size: int = 12):
@@ -588,7 +596,7 @@ def add_noise_to_border_only(image_tensor, seed: int, border_size: int, image_si
588
  # Convert back to tensor
589
  return torch.from_numpy(img_np).to(image_tensor.device)
590
 
591
- def _pipeline_standard(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 = False):
592
  emptylatentimage_5 = emptylatentimage.generate(
593
  width=image_size, height=image_size, batch_size=1
594
  )
@@ -651,7 +659,7 @@ def _pipeline_standard(prompt: str, qr_text: str, input_type: str, image_size: i
651
 
652
  for q in range(1):
653
  controlnetapplyadvanced_11 = controlnetapplyadvanced.apply_controlnet(
654
- strength=0.45,
655
  start_percent=0,
656
  end_percent=1,
657
  positive=get_value_at_index(cliptextencode_6, 0),
@@ -668,7 +676,7 @@ def _pipeline_standard(prompt: str, qr_text: str, input_type: str, image_size: i
668
  )
669
 
670
  controlnetapplyadvanced_13 = controlnetapplyadvanced.apply_controlnet(
671
- strength=0.45,
672
  start_percent=0,
673
  end_percent=1,
674
  positive=get_value_at_index(controlnetapplyadvanced_11, 0),
@@ -704,7 +712,7 @@ def _pipeline_standard(prompt: str, qr_text: str, input_type: str, image_size: i
704
  yield mid_pil, "First enhancement pass complete (step 2/3)… refining details"
705
 
706
  controlnetapplyadvanced_20 = controlnetapplyadvanced.apply_controlnet(
707
- strength=1,
708
  start_percent=0,
709
  end_percent=1,
710
  positive=get_value_at_index(cliptextencode_6, 0),
@@ -790,9 +798,19 @@ def _pipeline_artistic(prompt: str, qr_text: str, input_type: str, image_size: i
790
  base_qr_np = base_qr_np[0]
791
  base_qr_pil = Image.fromarray(base_qr_np)
792
 
 
 
 
 
 
 
 
 
 
793
  # Only add noise if there's a border (border_size > 0)
794
  if border_size > 0:
795
- yield base_qr_pil, "Generated base QR pattern... adding QR-like cubics to border (step 1/5)"
 
796
 
797
  # Add QR-like cubic patterns ONLY to border region (extends QR structure into border)
798
  # Density automatically matches QR code interior density for natural transition
@@ -808,11 +826,13 @@ def _pipeline_artistic(prompt: str, qr_text: str, input_type: str, image_size: i
808
  noisy_qr_np = (qr_with_border_noise.cpu().numpy() * 255).astype(np.uint8)
809
  noisy_qr_np = noisy_qr_np[0]
810
  noisy_qr_pil = Image.fromarray(noisy_qr_np)
811
- yield noisy_qr_pil, "Added QR-like cubics to border... enhancing with AI (step 2/5)"
 
812
  else:
813
  # No border, skip noise
814
  qr_with_border_noise = get_value_at_index(comfy_qr, 0)
815
- yield base_qr_pil, "Generated base QR pattern (no border)... enhancing with AI (step 1/4)"
 
816
 
817
  # Generate latent image
818
  latent_image = emptylatentimage.generate(
@@ -918,12 +938,8 @@ def _pipeline_artistic(prompt: str, qr_text: str, input_type: str, image_size: i
918
  first_pass_np = (first_pass_tensor.cpu().numpy() * 255).astype(np.uint8)
919
  first_pass_np = first_pass_np[0]
920
  first_pass_pil = Image.fromarray(first_pass_np)
921
- # Calculate step based on border and upscale
922
- if enable_upscale:
923
- 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"
924
- else:
925
- 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"
926
- yield first_pass_pil, step_msg
927
 
928
  # Final ControlNet pass (second pass - refinement)
929
  controlnet_apply_final = controlnetapplyadvanced.apply_controlnet(
@@ -971,8 +987,8 @@ def _pipeline_artistic(prompt: str, qr_text: str, input_type: str, image_size: i
971
  pre_upscale_np = (pre_upscale_tensor.cpu().numpy() * 255).astype(np.uint8)
972
  pre_upscale_np = pre_upscale_np[0]
973
  pre_upscale_pil = Image.fromarray(pre_upscale_np)
974
- step_msg = "Final refinement complete (step 4/5)... upscaling image" if border_size > 0 else "Final refinement complete (step 3/4)... upscaling image"
975
- yield pre_upscale_pil, step_msg
976
 
977
  # Upscale image with model (after final samples, before returning)
978
  upscaled = imageupscalewithmodel.upscale(
@@ -985,16 +1001,14 @@ def _pipeline_artistic(prompt: str, qr_text: str, input_type: str, image_size: i
985
  image_np = (image_tensor.cpu().numpy() * 255).astype(np.uint8)
986
  image_np = image_np[0]
987
  final_image = Image.fromarray(image_np)
988
- 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)"
989
- yield final_image, step_msg
990
  else:
991
  # No upscaling
992
  image_tensor = get_value_at_index(final_decoded, 0)
993
  image_np = (image_tensor.cpu().numpy() * 255).astype(np.uint8)
994
  image_np = image_np[0]
995
  final_image = Image.fromarray(image_np)
996
- 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)"
997
- yield final_image, step_msg
998
 
999
 
1000
  if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
@@ -1173,6 +1187,26 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
1173
  info="Seed value for reproducibility. Same seed with same settings will produce the same result."
1174
  )
1175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1176
  # The generate button
1177
  generate_btn = gr.Button("Generate Standard QR", variant="primary")
1178
 
@@ -1196,7 +1230,7 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
1196
  # When clicking the button, it will trigger the main function
1197
  generate_btn.click(
1198
  fn=generate_standard_qr,
1199
- 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],
1200
  outputs=[output_image, error_message, settings_output_standard, settings_accordion_standard]
1201
  )
1202
 
@@ -1217,6 +1251,8 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
1217
  seed,
1218
  enable_upscale,
1219
  enable_freeu_standard,
 
 
1220
  import_status_standard
1221
  ]
1222
  )
@@ -1562,6 +1598,26 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
1562
  info="Blur amount for artistic blending. Higher values create softer, more artistic effects. Range: 0.0-5.0, Default: 0.5"
1563
  )
1564
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1565
  # The generate button for artistic QR
1566
  artistic_generate_btn = gr.Button("Generate Artistic QR", variant="primary")
1567
 
@@ -1585,7 +1641,7 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
1585
  # When clicking the button, it will trigger the artistic function
1586
  artistic_generate_btn.click(
1587
  fn=generate_artistic_qr,
1588
- 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],
1589
  outputs=[artistic_output_image, artistic_error_message, settings_output_artistic, settings_accordion_artistic]
1590
  )
1591
 
@@ -1613,6 +1669,8 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
1613
  enable_sag,
1614
  sag_scale,
1615
  sag_blur_sigma,
 
 
1616
  import_status_artistic
1617
  ]
1618
  )
@@ -1641,7 +1699,9 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
1641
  6, # Border
1642
  "Medium (15%)", # Error correction
1643
  14, # Module size
1644
- "Square"
 
 
1645
  ],
1646
  [
1647
  "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",
@@ -1651,7 +1711,9 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
1651
  6, # Border
1652
  "High (30%)", # Error correction
1653
  16, # Module size
1654
- "Square"
 
 
1655
  ],
1656
  [
1657
  "a beautiful sunset over mountains, photorealistic, detailed landscape, golden hour, dramatic lighting, 8k, ultra detailed",
@@ -1661,7 +1723,9 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
1661
  6, # Border
1662
  "High (30%)", # Error correction
1663
  16, # Module size
1664
- "Square"
 
 
1665
  ],
1666
  [
1667
  "underwater scene with coral reef and tropical fish, photorealistic, detailed, crystal clear water, sunlight rays, 8k, ultra detailed",
@@ -1671,7 +1735,9 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
1671
  6, # Border
1672
  "High (30%)", # Error correction
1673
  16, # Module size
1674
- "Square"
 
 
1675
  ],
1676
  [
1677
  "futuristic cityscape with flying cars and neon lights, cyberpunk style, detailed architecture, night scene, 8k, ultra detailed",
@@ -1681,7 +1747,9 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
1681
  6, # Border
1682
  "High (30%)", # Error correction
1683
  16, # Module size
1684
- "Square"
 
 
1685
  ],
1686
  [
1687
  "vintage camera on wooden table, photorealistic, detailed textures, soft lighting, bokeh background, 8k, ultra detailed",
@@ -1691,7 +1759,9 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
1691
  6, # Border
1692
  "High (30%)", # Error correction
1693
  16, # Module size
1694
- "Square"
 
 
1695
  ],
1696
  [
1697
  "business card design, professional, modern, clean layout, corporate style, detailed, 8k, ultra detailed",
@@ -1704,34 +1774,40 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
1704
  "Square"
1705
  ],
1706
  [
1707
- "wifi network symbol, modern tech, digital art, glowing blue, detailed, 8k, ultra detailed",
1708
  "WIFI:T:WPA;S:MyNetwork;P:MyPassword123;;",
1709
  "Plain Text",
1710
- 576,
1711
- 4,
1712
- "Medium (15%)",
1713
- 12,
1714
- "Square"
 
 
1715
  ],
1716
  [
1717
- "calendar appointment reminder, organized planner, professional office, detailed, 8k, ultra detailed",
1718
  "BEGIN:VEVENT\nSUMMARY:Team Meeting\nDTSTART:20251115T140000Z\nDTEND:20251115T150000Z\nLOCATION:Conference Room A\nEND:VEVENT",
1719
  "Plain Text",
1720
- 832,
1721
- 4,
1722
- "Medium (15%)",
1723
- 12,
1724
- "Square"
 
 
1725
  ],
1726
  [
1727
- "location pin on map, travel destination, scenic view, detailed cartography, 8k, ultra detailed",
1728
  "geo:37.7749,-122.4194",
1729
  "Plain Text",
1730
- 512,
1731
- 4,
1732
- "Medium (15%)",
1733
- 12,
1734
- "Square"
 
 
1735
  ]
1736
  ]
1737
 
@@ -1745,7 +1821,9 @@ if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
1745
  artistic_border_size,
1746
  artistic_error_correction,
1747
  artistic_module_size,
1748
- artistic_module_drawer
 
 
1749
  ],
1750
  outputs=[artistic_output_image, artistic_error_message],
1751
  fn=generate_artistic_qr,
 
239
  model_management.load_models_gpu(valid_models)
240
 
241
  @spaces.GPU(duration=30)
242
+ def generate_qr_code_unified(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, pipeline: str = "standard", enable_upscale: bool = False, 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 = 1.5, controlnet_strength_first: float = 0.45, controlnet_strength_final: float = 0.7, controlnet_strength_standard_first: float = 0.45, controlnet_strength_standard_final: float = 1.0):
243
  # Only manipulate the text if it's a URL input type
244
  qr_text = text_input
245
  if input_type == "URL":
 
253
 
254
  with torch.inference_mode():
255
  if pipeline == "standard":
256
+ yield from _pipeline_standard(prompt, qr_text, input_type, image_size, border_size, error_correction, module_size, module_drawer, actual_seed, enable_upscale, controlnet_strength_standard_first, controlnet_strength_standard_final)
257
  else: # artistic
258
  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)
259
 
260
+ 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, controlnet_strength_standard_first: float = 0.45, controlnet_strength_standard_final: float = 1.0):
261
  """Wrapper function for standard QR generation"""
262
  # Get actual seed used (custom or random)
263
  actual_seed = seed if use_custom_seed else random.randint(1, 2**64)
 
276
  "seed": actual_seed,
277
  "use_custom_seed": True,
278
  "enable_upscale": enable_upscale,
279
+ "enable_freeu": enable_freeu,
280
+ "controlnet_strength_standard_first": controlnet_strength_standard_first,
281
+ "controlnet_strength_standard_final": controlnet_strength_standard_final
282
  }
283
  settings_json = generate_settings_json(settings_dict)
284
 
285
  # Generate QR and yield progressive results
286
+ 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, controlnet_strength_standard_first=controlnet_strength_standard_first, controlnet_strength_standard_final=controlnet_strength_standard_final)
287
 
288
  final_image = None
289
  final_status = None
 
303
  gr.update(visible=True) # Make accordion visible only at the end
304
  )
305
 
306
+ 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.70):
307
  """Wrapper function for artistic QR generation with FreeU and SAG parameters"""
308
  # Get actual seed used (custom or random)
309
  actual_seed = seed if use_custom_seed else random.randint(1, 2**64)
 
329
  "freeu_s2": freeu_s2,
330
  "enable_sag": enable_sag,
331
  "sag_scale": sag_scale,
332
+ "sag_blur_sigma": sag_blur_sigma,
333
+ "controlnet_strength_first": controlnet_strength_first,
334
+ "controlnet_strength_final": controlnet_strength_final
335
  }
336
  settings_json = generate_settings_json(settings_dict)
337
 
 
395
  return (
396
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
397
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
398
+ gr.update(), gr.update(), gr.update(), gr.update(),
399
  gr.update(value=error_msg, visible=True)
400
  )
401
 
 
412
  seed = params.get("seed", 718313)
413
  enable_upscale = params.get("enable_upscale", False)
414
  enable_freeu = params.get("enable_freeu", False)
415
+ controlnet_strength_standard_first = params.get("controlnet_strength_standard_first", 0.45)
416
+ controlnet_strength_standard_final = params.get("controlnet_strength_standard_final", 1.0)
417
 
418
  success_msg = "✅ Settings loaded successfully!"
419
  return (
420
  prompt, text_input, input_type, image_size, border_size,
421
  error_correction, module_size, module_drawer, use_custom_seed,
422
+ seed, enable_upscale, enable_freeu, controlnet_strength_standard_first,
423
+ controlnet_strength_standard_final, gr.update(value=success_msg, visible=True)
424
  )
425
 
426
  except json.JSONDecodeError as e:
 
428
  return (
429
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
430
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
431
+ gr.update(), gr.update(), gr.update(), gr.update(),
432
  gr.update(value=error_msg, visible=True)
433
  )
434
  except Exception as e:
 
436
  return (
437
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
438
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
439
+ gr.update(), gr.update(), gr.update(), gr.update(),
440
  gr.update(value=error_msg, visible=True)
441
  )
442
 
 
454
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
455
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
456
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
457
+ gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
458
+ gr.update(), gr.update(value=error_msg, visible=True)
459
  )
460
 
461
  # Extract parameters with defaults
 
478
  enable_sag = params.get("enable_sag", True)
479
  sag_scale = params.get("sag_scale", 0.5)
480
  sag_blur_sigma = params.get("sag_blur_sigma", 0.5)
481
+ controlnet_strength_first = params.get("controlnet_strength_first", 0.45)
482
+ controlnet_strength_final = params.get("controlnet_strength_final", 0.7)
483
 
484
  success_msg = "✅ Settings loaded successfully!"
485
  return (
486
  prompt, text_input, input_type, image_size, border_size,
487
  error_correction, module_size, module_drawer, use_custom_seed,
488
  seed, enable_upscale, enable_freeu, freeu_b1, freeu_b2, freeu_s1,
489
+ freeu_s2, enable_sag, sag_scale, sag_blur_sigma, controlnet_strength_first,
490
+ controlnet_strength_final, gr.update(value=success_msg, visible=True)
491
  )
492
 
493
  except json.JSONDecodeError as e:
 
496
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
497
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
498
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
499
+ gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
500
+ gr.update(), gr.update(value=error_msg, visible=True)
501
  )
502
  except Exception as e:
503
  error_msg = f"❌ Error loading settings: {str(e)}"
 
505
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
506
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
507
  gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
508
+ gr.update(), gr.update(), gr.update(), gr.update(), gr.update(),
509
+ gr.update(), gr.update(value=error_msg, visible=True)
510
  )
511
 
512
  def add_noise_to_border_only(image_tensor, seed: int, border_size: int, image_size: int, module_size: int = 12):
 
596
  # Convert back to tensor
597
  return torch.from_numpy(img_np).to(image_tensor.device)
598
 
599
+ def _pipeline_standard(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 = False, controlnet_strength_first: float = 0.45, controlnet_strength_final: float = 1.0):
600
  emptylatentimage_5 = emptylatentimage.generate(
601
  width=image_size, height=image_size, batch_size=1
602
  )
 
659
 
660
  for q in range(1):
661
  controlnetapplyadvanced_11 = controlnetapplyadvanced.apply_controlnet(
662
+ strength=controlnet_strength_first,
663
  start_percent=0,
664
  end_percent=1,
665
  positive=get_value_at_index(cliptextencode_6, 0),
 
676
  )
677
 
678
  controlnetapplyadvanced_13 = controlnetapplyadvanced.apply_controlnet(
679
+ strength=controlnet_strength_first,
680
  start_percent=0,
681
  end_percent=1,
682
  positive=get_value_at_index(controlnetapplyadvanced_11, 0),
 
712
  yield mid_pil, "First enhancement pass complete (step 2/3)… refining details"
713
 
714
  controlnetapplyadvanced_20 = controlnetapplyadvanced.apply_controlnet(
715
+ strength=controlnet_strength_final,
716
  start_percent=0,
717
  end_percent=1,
718
  positive=get_value_at_index(cliptextencode_6, 0),
 
798
  base_qr_np = base_qr_np[0]
799
  base_qr_pil = Image.fromarray(base_qr_np)
800
 
801
+ # Calculate total steps based on border and upscale
802
+ total_steps = 3 # Base: first pass, final refinement, final result
803
+ if border_size > 0:
804
+ total_steps += 1 # Add border noise step
805
+ if enable_upscale:
806
+ total_steps += 1 # Add upscale step
807
+
808
+ current_step = 1
809
+
810
  # Only add noise if there's a border (border_size > 0)
811
  if border_size > 0:
812
+ yield base_qr_pil, f"Generated base QR pattern... adding QR-like cubics to border (step {current_step}/{total_steps})"
813
+ current_step += 1
814
 
815
  # Add QR-like cubic patterns ONLY to border region (extends QR structure into border)
816
  # Density automatically matches QR code interior density for natural transition
 
826
  noisy_qr_np = (qr_with_border_noise.cpu().numpy() * 255).astype(np.uint8)
827
  noisy_qr_np = noisy_qr_np[0]
828
  noisy_qr_pil = Image.fromarray(noisy_qr_np)
829
+ yield noisy_qr_pil, f"Added QR-like cubics to border... enhancing with AI (step {current_step}/{total_steps})"
830
+ current_step += 1
831
  else:
832
  # No border, skip noise
833
  qr_with_border_noise = get_value_at_index(comfy_qr, 0)
834
+ yield base_qr_pil, f"Generated base QR pattern (no border)... enhancing with AI (step {current_step}/{total_steps})"
835
+ current_step += 1
836
 
837
  # Generate latent image
838
  latent_image = emptylatentimage.generate(
 
938
  first_pass_np = (first_pass_tensor.cpu().numpy() * 255).astype(np.uint8)
939
  first_pass_np = first_pass_np[0]
940
  first_pass_pil = Image.fromarray(first_pass_np)
941
+ yield first_pass_pil, f"First enhancement pass complete (step {current_step}/{total_steps})... final refinement pass"
942
+ current_step += 1
 
 
 
 
943
 
944
  # Final ControlNet pass (second pass - refinement)
945
  controlnet_apply_final = controlnetapplyadvanced.apply_controlnet(
 
987
  pre_upscale_np = (pre_upscale_tensor.cpu().numpy() * 255).astype(np.uint8)
988
  pre_upscale_np = pre_upscale_np[0]
989
  pre_upscale_pil = Image.fromarray(pre_upscale_np)
990
+ yield pre_upscale_pil, f"Final refinement complete (step {current_step}/{total_steps})... upscaling image"
991
+ current_step += 1
992
 
993
  # Upscale image with model (after final samples, before returning)
994
  upscaled = imageupscalewithmodel.upscale(
 
1001
  image_np = (image_tensor.cpu().numpy() * 255).astype(np.uint8)
1002
  image_np = image_np[0]
1003
  final_image = Image.fromarray(image_np)
1004
+ yield final_image, f"No errors, all good! Final artistic QR code generated and upscaled. (step {current_step}/{total_steps})"
 
1005
  else:
1006
  # No upscaling
1007
  image_tensor = get_value_at_index(final_decoded, 0)
1008
  image_np = (image_tensor.cpu().numpy() * 255).astype(np.uint8)
1009
  image_np = image_np[0]
1010
  final_image = Image.fromarray(image_np)
1011
+ yield final_image, f"No errors, all good! Final artistic QR code generated. (step {current_step}/{total_steps})"
 
1012
 
1013
 
1014
  if __name__ == "__main__" and not os.environ.get('QR_TESTING_MODE'):
 
1187
  info="Seed value for reproducibility. Same seed with same settings will produce the same result."
1188
  )
1189
 
1190
+ # ControlNet Strength Parameters
1191
+ gr.Markdown("### ControlNet Strength (QR Code Preservation)")
1192
+ gr.Markdown("**IMPORTANT:** Lower values preserve QR structure better (more scannable). Higher values create more artistic effects but may reduce scannability.")
1193
+ controlnet_strength_standard_first = gr.Slider(
1194
+ minimum=0.0,
1195
+ maximum=1.0,
1196
+ step=0.05,
1197
+ value=0.45,
1198
+ label="First Pass Strength (Brightness + Tile)",
1199
+ info="Controls how much the AI modifies the QR in both ControlNet passes. LOWER = more scannable, HIGHER = more artistic. Try 0.35-0.50 for good balance. Default: 0.45"
1200
+ )
1201
+ controlnet_strength_standard_final = gr.Slider(
1202
+ minimum=0.0,
1203
+ maximum=1.0,
1204
+ step=0.05,
1205
+ value=1.0,
1206
+ label="Final Pass Strength (Tile Refinement)",
1207
+ info="Controls the final tile ControlNet pass strength. Usually kept at 1.0 for clarity. Default: 1.0"
1208
+ )
1209
+
1210
  # The generate button
1211
  generate_btn = gr.Button("Generate Standard QR", variant="primary")
1212
 
 
1230
  # When clicking the button, it will trigger the main function
1231
  generate_btn.click(
1232
  fn=generate_standard_qr,
1233
+ 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, controlnet_strength_standard_first, controlnet_strength_standard_final],
1234
  outputs=[output_image, error_message, settings_output_standard, settings_accordion_standard]
1235
  )
1236
 
 
1251
  seed,
1252
  enable_upscale,
1253
  enable_freeu_standard,
1254
+ controlnet_strength_standard_first,
1255
+ controlnet_strength_standard_final,
1256
  import_status_standard
1257
  ]
1258
  )
 
1598
  info="Blur amount for artistic blending. Higher values create softer, more artistic effects. Range: 0.0-5.0, Default: 0.5"
1599
  )
1600
 
1601
+ # ControlNet Strength Parameters
1602
+ gr.Markdown("### ControlNet Strength (QR Code Preservation)")
1603
+ gr.Markdown("**IMPORTANT:** Lower values preserve QR structure better (more scannable). Higher values create more artistic effects but may reduce scannability.")
1604
+ controlnet_strength_first = gr.Slider(
1605
+ minimum=0.0,
1606
+ maximum=1.0,
1607
+ step=0.05,
1608
+ value=0.45,
1609
+ label="First Pass Strength",
1610
+ info="Controls how much the AI modifies the QR in the first pass. LOWER = more scannable, HIGHER = more artistic. Try 0.30-0.40 for better scannability. Default: 0.45"
1611
+ )
1612
+ controlnet_strength_final = gr.Slider(
1613
+ minimum=0.0,
1614
+ maximum=1.0,
1615
+ step=0.05,
1616
+ value=0.7,
1617
+ label="Final Pass Strength",
1618
+ info="Controls how much the AI modifies the QR in the refinement pass. LOWER = preserves QR structure, HIGHER = more creative. Try 0.55-0.65 for balance. Default: 0.70"
1619
+ )
1620
+
1621
  # The generate button for artistic QR
1622
  artistic_generate_btn = gr.Button("Generate Artistic QR", variant="primary")
1623
 
 
1641
  # When clicking the button, it will trigger the artistic function
1642
  artistic_generate_btn.click(
1643
  fn=generate_artistic_qr,
1644
+ 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, controlnet_strength_first, controlnet_strength_final],
1645
  outputs=[artistic_output_image, artistic_error_message, settings_output_artistic, settings_accordion_artistic]
1646
  )
1647
 
 
1669
  enable_sag,
1670
  sag_scale,
1671
  sag_blur_sigma,
1672
+ controlnet_strength_first,
1673
+ controlnet_strength_final,
1674
  import_status_artistic
1675
  ]
1676
  )
 
1699
  6, # Border
1700
  "Medium (15%)", # Error correction
1701
  14, # Module size
1702
+ "Square",
1703
+ True, # use_custom_seed
1704
+ 718313 # seed
1705
  ],
1706
  [
1707
  "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",
 
1711
  6, # Border
1712
  "High (30%)", # Error correction
1713
  16, # Module size
1714
+ "Square",
1715
+ True, # use_custom_seed
1716
+ 718313 # seed
1717
  ],
1718
  [
1719
  "a beautiful sunset over mountains, photorealistic, detailed landscape, golden hour, dramatic lighting, 8k, ultra detailed",
 
1723
  6, # Border
1724
  "High (30%)", # Error correction
1725
  16, # Module size
1726
+ "Square",
1727
+ True, # use_custom_seed
1728
+ 718313 # seed
1729
  ],
1730
  [
1731
  "underwater scene with coral reef and tropical fish, photorealistic, detailed, crystal clear water, sunlight rays, 8k, ultra detailed",
 
1735
  6, # Border
1736
  "High (30%)", # Error correction
1737
  16, # Module size
1738
+ "Square",
1739
+ True, # use_custom_seed
1740
+ 718313 # seed
1741
  ],
1742
  [
1743
  "futuristic cityscape with flying cars and neon lights, cyberpunk style, detailed architecture, night scene, 8k, ultra detailed",
 
1747
  6, # Border
1748
  "High (30%)", # Error correction
1749
  16, # Module size
1750
+ "Square",
1751
+ True, # use_custom_seed
1752
+ 718313 # seed
1753
  ],
1754
  [
1755
  "vintage camera on wooden table, photorealistic, detailed textures, soft lighting, bokeh background, 8k, ultra detailed",
 
1759
  6, # Border
1760
  "High (30%)", # Error correction
1761
  16, # Module size
1762
+ "Square",
1763
+ True, # use_custom_seed
1764
+ 718313 # seed
1765
  ],
1766
  [
1767
  "business card design, professional, modern, clean layout, corporate style, detailed, 8k, ultra detailed",
 
1774
  "Square"
1775
  ],
1776
  [
1777
+ "aerial bird view of ancient Roman city, cobblestone streets and pathways forming intricate patterns, vintage illustration style, sepia tones, aged parchment look, detailed architecture, 8k, ultra detailed",
1778
  "WIFI:T:WPA;S:MyNetwork;P:MyPassword123;;",
1779
  "Plain Text",
1780
+ 832, # Image size
1781
+ 6, # Border
1782
+ "High (30%)", # Error correction
1783
+ 16, # Module size
1784
+ "Square",
1785
+ True, # use_custom_seed
1786
+ 718313 # seed
1787
  ],
1788
  [
1789
+ "ancient stone sundial in Mediterranean garden, olive trees, dappled sunlight through leaves, weathered stone texture, peaceful afternoon scene, photorealistic, detailed, 8k, ultra detailed",
1790
  "BEGIN:VEVENT\nSUMMARY:Team Meeting\nDTSTART:20251115T140000Z\nDTEND:20251115T150000Z\nLOCATION:Conference Room A\nEND:VEVENT",
1791
  "Plain Text",
1792
+ 1024, # Image size
1793
+ 6, # Border
1794
+ "High (30%)", # Error correction
1795
+ 14, # Module size
1796
+ "Square",
1797
+ True, # use_custom_seed
1798
+ 413468 # seed (custom for meeting)
1799
  ],
1800
  [
1801
+ "aerial view of terraced rice fields on mountainside, winding pathways between green paddies, Asian countryside, bird's eye perspective, detailed landscape, golden hour lighting, photorealistic, 8k, ultra detailed",
1802
  "geo:37.7749,-122.4194",
1803
  "Plain Text",
1804
+ 704, # Image size (default)
1805
+ 6, # Border
1806
+ "High (30%)", # Error correction
1807
+ 16, # Module size
1808
+ "Square",
1809
+ True, # use_custom_seed
1810
+ 962359 # seed (custom for location)
1811
  ]
1812
  ]
1813
 
 
1821
  artistic_border_size,
1822
  artistic_error_correction,
1823
  artistic_module_size,
1824
+ artistic_module_drawer,
1825
+ artistic_use_custom_seed,
1826
+ artistic_seed
1827
  ],
1828
  outputs=[artistic_output_image, artistic_error_message],
1829
  fn=generate_artistic_qr,