Julian Bilcke commited on
Commit
3678ee4
·
1 Parent(s): 4cf61fa
Files changed (1) hide show
  1. app.py +89 -93
app.py CHANGED
@@ -520,26 +520,31 @@ def create_single_page_pdf(images: List[Image.Image], layout_id: str, num_images
520
  layout = next((l for l in layouts if l["id"] == layout_id), None)
521
 
522
  if not layout:
523
- # Fallback to default grid layout
524
  if num_images == 1:
525
- positions = [[0.05, 0.05, 0.9, 0.9]]
526
  elif num_images == 2:
527
- positions = [[0.05, 0.05, 0.425, 0.9], [0.525, 0.05, 0.425, 0.9]]
 
528
  elif num_images == 3:
529
- positions = [[0.05, 0.05, 0.283, 0.9], [0.358, 0.05, 0.283, 0.9], [0.666, 0.05, 0.283, 0.9]]
 
530
  elif num_images == 4:
531
- positions = [[0.05, 0.05, 0.425, 0.425], [0.525, 0.05, 0.425, 0.425],
532
- [0.05, 0.525, 0.425, 0.425], [0.525, 0.525, 0.425, 0.425]]
 
533
  elif num_images == 5:
534
- positions = [[0.05, 0.05, 0.9, 0.3], [0.05, 0.4, 0.283, 0.55], [0.358, 0.4, 0.283, 0.55],
535
- [0.666, 0.4, 0.283, 0.275], [0.666, 0.7, 0.283, 0.275]]
 
536
  elif num_images == 6:
537
- positions = [[0.05, 0.05, 0.425, 0.283], [0.525, 0.05, 0.425, 0.283],
538
- [0.05, 0.358, 0.425, 0.283], [0.525, 0.358, 0.425, 0.283],
539
- [0.05, 0.666, 0.425, 0.283], [0.525, 0.666, 0.425, 0.283]]
 
540
  else:
541
  # For more than 6, create a simple grid
542
- positions = [[0.05, 0.05, 0.9, 0.9]]
543
  else:
544
  positions = layout["positions"]
545
 
@@ -550,27 +555,13 @@ def create_single_page_pdf(images: List[Image.Image], layout_id: str, num_images
550
 
551
  x_rel, y_rel, w_rel, h_rel = pos
552
 
553
- # Pack images more tightly - significantly reduce empty space
554
- # Minimal padding between panels (0.5% of page dimensions)
555
- padding = 0.005
556
 
557
- # Scale up positions and sizes to fill more of the page
558
- # This brings everything closer to the edges and each other
559
- scale_factor = 1.15 # Increase overall scale by 15%
560
 
561
- # Calculate centered scaling to maintain layout proportions
562
- center_x = 0.5
563
- center_y = 0.5
564
-
565
- # Scale positions relative to center
566
- x_rel = center_x + (x_rel - center_x) * scale_factor
567
- y_rel = center_y + (y_rel - center_y) * scale_factor
568
-
569
- # Scale sizes
570
- w_rel = w_rel * scale_factor
571
- h_rel = h_rel * scale_factor
572
-
573
- # Apply bounds checking to prevent overflow
574
  if x_rel < padding:
575
  x_rel = padding
576
  if y_rel < padding:
@@ -862,21 +853,40 @@ with gr.Blocks(css=css) as demo:
862
  </div>
863
  """)
864
  gr.Markdown("This demo uses [Qwen-Image-Lightning](https://huggingface.co/lightx2v/Qwen-Image-Lightning). Hugigng Face PRO users can perform more generations.")
 
 
865
  with gr.Row():
866
  prompt = gr.Text(
867
  label="Prompt",
868
  show_label=False,
869
  placeholder="Enter your prompt",
870
  container=False,
 
871
  )
872
- with gr.Column(scale=0):
873
- run_button = gr.Button("Generate page 1", variant="primary")
874
- reset_button = gr.Button("Reset", variant="secondary")
875
 
876
- # New row for Style Preset and Page Layout
877
  with gr.Row():
 
878
  with gr.Column(scale=1):
879
- # Number of images slider (affects layout choices)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
880
  num_images_slider = gr.Slider(
881
  label="Images per page",
882
  minimum=1,
@@ -886,7 +896,7 @@ with gr.Blocks(css=css) as demo:
886
  info="Number of images to generate for the PDF (1-6)"
887
  )
888
 
889
- with gr.Column(scale=2):
890
  layout_dropdown = gr.Dropdown(
891
  label="Page Layout",
892
  choices=[("Full Page", "full_page")],
@@ -895,48 +905,52 @@ with gr.Blocks(css=css) as demo:
895
  info="How images are arranged on the page"
896
  )
897
 
898
- with gr.Column(scale=2):
899
- # Create dropdown choices from loaded presets
900
- style_choices = [(preset["label"], key) for key, preset in STYLE_PRESETS.items()]
901
- style_preset = gr.Dropdown(
902
- label="Style Preset",
903
- choices=style_choices,
904
- value="no_style",
905
- interactive=True
906
- )
907
-
908
- with gr.Column(scale=2):
909
- custom_style_text = gr.Textbox(
910
- label="Custom Style Text",
911
- placeholder="Enter custom style (e.g., 'oil painting')",
912
- visible=False,
913
- lines=1
914
- )
915
-
916
- with gr.Row():
917
- with gr.Column():
918
- pdf_preview = PDF(label="PDF Preview", show_label=True, height=600, elem_id="pdf-preview")
919
  pdf_output = gr.File(label="Download PDF", show_label=True, elem_id="pdf-download")
 
920
  gr.Markdown("""**Note:** Your images and PDF are saved for up to 24 hours.
921
  You can continue adding pages (up to 128) by clicking the generate button.""")
922
 
923
- with gr.Accordion("Advanced Settings", open=False):
924
- with gr.Row():
925
- guidance_scale = gr.Slider(
926
- label="Guidance scale (True CFG Scale)",
927
- minimum=1.0,
928
- maximum=5.0,
929
- step=0.1,
930
- value=1.0,
931
- )
932
-
933
- num_inference_steps = gr.Slider(
934
- label="Number of inference steps",
935
- minimum=4,
936
- maximum=28,
937
- step=1,
938
- value=8,
939
- )
 
 
 
 
 
940
 
941
  # Add interaction to show/hide custom style text field
942
  def toggle_custom_style(style_value):
@@ -959,24 +973,6 @@ with gr.Blocks(css=css) as demo:
959
  outputs=[layout_dropdown]
960
  )
961
 
962
- # Update examples to show some with different styles and image counts
963
- styled_examples = [
964
- ["A capybara wearing a suit holding a sign that reads Hello World", "no_style", "", 1],
965
- ["sharks raining down on san francisco", "anime", "", 2],
966
- ["A beautiful landscape with mountains and a lake", "watercolor", "", 3],
967
- ["A knight fighting a dragon", "medieval", "", 4],
968
- ["Space battle with laser beams", "sci-fi", "", 5],
969
- ["Detective investigating a mystery", "noir", "", 6],
970
- ]
971
-
972
- gr.Examples(
973
- examples=styled_examples,
974
- inputs=[prompt, style_preset, custom_style_text, num_images_slider],
975
- outputs=None, # Don't show outputs for examples
976
- fn=None,
977
- cache_examples=False
978
- )
979
-
980
  # Define the main generation event
981
  generation_event = gr.on(
982
  triggers=[run_button.click, prompt.submit],
 
520
  layout = next((l for l in layouts if l["id"] == layout_id), None)
521
 
522
  if not layout:
523
+ # Fallback to default grid layout with proper spacing
524
  if num_images == 1:
525
+ positions = [[0.02, 0.02, 0.96, 0.96]]
526
  elif num_images == 2:
527
+ # Horizontal split with gap
528
+ positions = [[0.02, 0.02, 0.47, 0.96], [0.51, 0.02, 0.47, 0.96]]
529
  elif num_images == 3:
530
+ # Three horizontal panels with gaps
531
+ positions = [[0.02, 0.2, 0.31, 0.6], [0.345, 0.2, 0.31, 0.6], [0.67, 0.2, 0.31, 0.6]]
532
  elif num_images == 4:
533
+ # 2x2 grid with gaps
534
+ positions = [[0.02, 0.02, 0.47, 0.47], [0.51, 0.02, 0.47, 0.47],
535
+ [0.02, 0.51, 0.47, 0.47], [0.51, 0.51, 0.47, 0.47]]
536
  elif num_images == 5:
537
+ # Hero top with 4 small panels below
538
+ positions = [[0.02, 0.02, 0.96, 0.44], [0.02, 0.48, 0.31, 0.5], [0.345, 0.48, 0.31, 0.5],
539
+ [0.67, 0.48, 0.31, 0.24], [0.67, 0.74, 0.31, 0.24]]
540
  elif num_images == 6:
541
+ # 2x3 grid with gaps
542
+ positions = [[0.02, 0.02, 0.47, 0.31], [0.51, 0.02, 0.47, 0.31],
543
+ [0.02, 0.345, 0.47, 0.31], [0.51, 0.345, 0.47, 0.31],
544
+ [0.02, 0.67, 0.47, 0.31], [0.51, 0.67, 0.47, 0.31]]
545
  else:
546
  # For more than 6, create a simple grid
547
+ positions = [[0.02, 0.02, 0.96, 0.96]]
548
  else:
549
  positions = layout["positions"]
550
 
 
555
 
556
  x_rel, y_rel, w_rel, h_rel = pos
557
 
558
+ # Add small padding between panels (1% of page dimensions)
559
+ padding = 0.01
 
560
 
561
+ # Don't scale up - use the positions as defined in the layout
562
+ # This prevents overlapping when there are multiple images
 
563
 
564
+ # Apply padding to prevent images from touching edges
 
 
 
 
 
 
 
 
 
 
 
 
565
  if x_rel < padding:
566
  x_rel = padding
567
  if y_rel < padding:
 
853
  </div>
854
  """)
855
  gr.Markdown("This demo uses [Qwen-Image-Lightning](https://huggingface.co/lightx2v/Qwen-Image-Lightning). Hugigng Face PRO users can perform more generations.")
856
+
857
+ # First row: prompt input, generate button, reset button
858
  with gr.Row():
859
  prompt = gr.Text(
860
  label="Prompt",
861
  show_label=False,
862
  placeholder="Enter your prompt",
863
  container=False,
864
+ scale=4
865
  )
866
+ run_button = gr.Button("Generate page 1", variant="primary", scale=1)
867
+ reset_button = gr.Button("Reset", variant="secondary", scale=1)
 
868
 
869
+ # Second row: 1/3 controls on left, 2/3 PDF preview on right
870
  with gr.Row():
871
+ # Left column (1/3) - Controls
872
  with gr.Column(scale=1):
873
+ # Create dropdown choices from loaded presets
874
+ style_choices = [(preset["label"], key) for key, preset in STYLE_PRESETS.items()]
875
+ style_preset = gr.Dropdown(
876
+ label="Style Preset",
877
+ choices=style_choices,
878
+ value="no_style",
879
+ interactive=True
880
+ )
881
+
882
+ custom_style_text = gr.Textbox(
883
+ label="Custom Style Text",
884
+ placeholder="Enter custom style (e.g., 'oil painting')",
885
+ visible=False,
886
+ lines=1
887
+ )
888
+
889
+ # Number of images slider
890
  num_images_slider = gr.Slider(
891
  label="Images per page",
892
  minimum=1,
 
896
  info="Number of images to generate for the PDF (1-6)"
897
  )
898
 
899
+ # Page layout dropdown
900
  layout_dropdown = gr.Dropdown(
901
  label="Page Layout",
902
  choices=[("Full Page", "full_page")],
 
905
  info="How images are arranged on the page"
906
  )
907
 
908
+ # Advanced settings accordion
909
+ with gr.Accordion("Advanced Settings", open=False):
910
+ guidance_scale = gr.Slider(
911
+ label="Guidance scale (True CFG Scale)",
912
+ minimum=1.0,
913
+ maximum=5.0,
914
+ step=0.1,
915
+ value=1.0,
916
+ )
917
+
918
+ num_inference_steps = gr.Slider(
919
+ label="Number of inference steps",
920
+ minimum=4,
921
+ maximum=28,
922
+ step=1,
923
+ value=8,
924
+ )
925
+
926
+ # Download link
 
 
927
  pdf_output = gr.File(label="Download PDF", show_label=True, elem_id="pdf-download")
928
+
929
  gr.Markdown("""**Note:** Your images and PDF are saved for up to 24 hours.
930
  You can continue adding pages (up to 128) by clicking the generate button.""")
931
 
932
+ # Examples section in the left column
933
+ with gr.Accordion("Examples", open=True):
934
+ styled_examples = [
935
+ ["A capybara wearing a suit holding a sign that reads Hello World", "no_style", "", 1],
936
+ ["sharks raining down on san francisco", "anime", "", 2],
937
+ ["A beautiful landscape with mountains and a lake", "watercolor", "", 3],
938
+ ["A knight fighting a dragon", "medieval", "", 4],
939
+ ["Space battle with laser beams", "sci-fi", "", 5],
940
+ ["Detective investigating a mystery", "noir", "", 6],
941
+ ]
942
+
943
+ gr.Examples(
944
+ examples=styled_examples,
945
+ inputs=[prompt, style_preset, custom_style_text, num_images_slider],
946
+ outputs=None, # Don't show outputs for examples
947
+ fn=None,
948
+ cache_examples=False
949
+ )
950
+
951
+ # Right column (2/3) - PDF Preview
952
+ with gr.Column(scale=2):
953
+ pdf_preview = PDF(label="PDF Preview", show_label=True, height=700, elem_id="pdf-preview")
954
 
955
  # Add interaction to show/hide custom style text field
956
  def toggle_custom_style(style_value):
 
973
  outputs=[layout_dropdown]
974
  )
975
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
976
  # Define the main generation event
977
  generation_event = gr.on(
978
  triggers=[run_button.click, prompt.submit],