awacke1 commited on
Commit
87e82bc
·
verified ·
1 Parent(s): c5555e1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +27 -28
app.py CHANGED
@@ -18,9 +18,9 @@ st.set_page_config(
18
  initial_sidebar_state="expanded",
19
  )
20
 
21
- st.title("🖼️ Image → PDF • Comic-Book Layout Generator")
22
  st.markdown(
23
- "Upload images, choose aspect ratio, filter by shape, reorder visually, and generate a PDF."
24
  )
25
 
26
  # --- Sidebar: Page Settings -----------------------------
@@ -55,30 +55,32 @@ uploaded = st.file_uploader(
55
 
56
  ordered_files = []
57
  if uploaded:
58
- # ➊ Collect metadata
59
  records = []
60
  for idx, f in enumerate(uploaded):
61
  im = Image.open(f)
62
  w, h = im.size
63
  ar = round(w / h, 2)
64
  orient = "Square" if 0.9 <= ar <= 1.1 else ("Landscape" if ar > 1.1 else "Portrait")
65
- records.append({"filename": f.name, "width": w, "height": h,
66
- "aspect_ratio": ar, "orientation": orient, "order": idx})
 
 
 
 
 
 
67
  df = pd.DataFrame(records)
68
 
69
- # ➋ Filter by orientation
70
  dims = st.sidebar.multiselect(
71
  "Include orientations:", options=["Landscape","Portrait","Square"],
72
  default=["Landscape","Portrait","Square"]
73
  )
74
  df = df[df["orientation"].isin(dims)].reset_index(drop=True)
75
 
76
- # ➌ Show metadata table
77
  st.markdown("#### Image Metadata")
78
  st.dataframe(df.style.format({"aspect_ratio": "{:.2f}"}), use_container_width=True)
79
 
80
- # Visual reorder via Data Editor
81
- st.markdown("#### Reorder Panels (drag rows or adjust 'order')")
82
  try:
83
  edited = st.experimental_data_editor(
84
  df, num_rows="fixed", use_container_width=True
@@ -97,7 +99,6 @@ if uploaded:
97
  )
98
  ordered_df = edited.sort_values("order").reset_index(drop=True)
99
 
100
- # Map filenames to ordered files
101
  name2file = {f.name: f for f in uploaded}
102
  ordered_files = [name2file[n] for n in ordered_df["filename"] if n in name2file]
103
 
@@ -109,26 +110,24 @@ def top_n_words(names, n=5):
109
  words += re.findall(r"\w+", stem.lower())
110
  return [w for w,_ in Counter(words).most_common(n)]
111
 
112
- def make_comic_pdf(images, w_pt, h_pt):
 
113
  buf = io.BytesIO()
114
- c = canvas.Canvas(buf, pagesize=(w_pt, h_pt))
115
- N = len(images)
116
- cols = int(math.ceil(math.sqrt(N)))
117
- rows = int(math.ceil(N/cols))
118
- pw, ph = w_pt/cols, h_pt/rows
119
- for idx, f in enumerate(images):
120
  im = Image.open(f)
121
  iw, ih = im.size
122
- tar = pw/ph; ar = iw/ih
123
- if ar>tar:
124
- nw = int(ih*tar); left=(iw-nw)//2; im=im.crop((left,0,left+nw,ih))
125
- else:
126
- nh = int(iw/tar); top=(ih-nh)//2; im=im.crop((0,top,iw,top+nh))
127
- im = im.resize((int(pw),int(ph)), Image.LANCZOS)
128
- col, row = idx%cols, idx//cols
129
- x, y = col*pw, h_pt - (row+1)*ph
130
- c.drawImage(ImageReader(im), x, y, pw, ph, preserveAspectRatio=False, mask='auto')
131
- c.showPage(); c.save(); buf.seek(0)
 
132
  return buf.getvalue()
133
 
134
  # --- Generate & Download -------------------------------
@@ -141,7 +140,7 @@ if st.button("🎉 Generate PDF"):
141
  words = top_n_words([f.name for f in ordered_files])
142
  slug = "-".join(words)
143
  fname = f"{date_s}-{slug}.pdf"
144
- pdf = make_comic_pdf(ordered_files, page_width, page_height)
145
  st.success(f"✅ PDF ready: **{fname}**")
146
  st.download_button("⬇️ Download PDF", data=pdf, file_name=fname, mime="application/pdf")
147
  st.markdown("#### Preview")
 
18
  initial_sidebar_state="expanded",
19
  )
20
 
21
+ st.title("🖼️ Image → PDF • Full-Page Layout Generator")
22
  st.markdown(
23
+ "Upload images, filter by orientation, reorder visually, and generate a PDF with each image filling its own page."
24
  )
25
 
26
  # --- Sidebar: Page Settings -----------------------------
 
55
 
56
  ordered_files = []
57
  if uploaded:
 
58
  records = []
59
  for idx, f in enumerate(uploaded):
60
  im = Image.open(f)
61
  w, h = im.size
62
  ar = round(w / h, 2)
63
  orient = "Square" if 0.9 <= ar <= 1.1 else ("Landscape" if ar > 1.1 else "Portrait")
64
+ records.append({
65
+ "filename": f.name,
66
+ "width": w,
67
+ "height": h,
68
+ "aspect_ratio": ar,
69
+ "orientation": orient,
70
+ "order": idx
71
+ })
72
  df = pd.DataFrame(records)
73
 
 
74
  dims = st.sidebar.multiselect(
75
  "Include orientations:", options=["Landscape","Portrait","Square"],
76
  default=["Landscape","Portrait","Square"]
77
  )
78
  df = df[df["orientation"].isin(dims)].reset_index(drop=True)
79
 
 
80
  st.markdown("#### Image Metadata")
81
  st.dataframe(df.style.format({"aspect_ratio": "{:.2f}"}), use_container_width=True)
82
 
83
+ st.markdown("#### Reorder Panels")
 
84
  try:
85
  edited = st.experimental_data_editor(
86
  df, num_rows="fixed", use_container_width=True
 
99
  )
100
  ordered_df = edited.sort_values("order").reset_index(drop=True)
101
 
 
102
  name2file = {f.name: f for f in uploaded}
103
  ordered_files = [name2file[n] for n in ordered_df["filename"] if n in name2file]
104
 
 
110
  words += re.findall(r"\w+", stem.lower())
111
  return [w for w,_ in Counter(words).most_common(n)]
112
 
113
+
114
+ def make_fullpage_pdf(images, w_pt, h_pt):
115
  buf = io.BytesIO()
116
+ c = canvas.Canvas(buf, pagesize=(w_pt, h_ht := h_pt))
117
+ for f in images:
 
 
 
 
118
  im = Image.open(f)
119
  iw, ih = im.size
120
+ # calculate scale to fit page
121
+ scale = min(w_pt/iw, h_pt/ih)
122
+ new_w = int(iw * scale)
123
+ new_h = int(ih * scale)
124
+ x = (w_pt - new_w)/2
125
+ y = (h_pt - new_h)/2
126
+ im = im.resize((new_w, new_h), Image.LANCZOS)
127
+ c.drawImage(ImageReader(im), x, y, new_w, new_h, preserveAspectRatio=False, mask='auto')
128
+ c.showPage()
129
+ c.save()
130
+ buf.seek(0)
131
  return buf.getvalue()
132
 
133
  # --- Generate & Download -------------------------------
 
140
  words = top_n_words([f.name for f in ordered_files])
141
  slug = "-".join(words)
142
  fname = f"{date_s}-{slug}.pdf"
143
+ pdf = make_fullpage_pdf(ordered_files, page_width, page_height)
144
  st.success(f"✅ PDF ready: **{fname}**")
145
  st.download_button("⬇️ Download PDF", data=pdf, file_name=fname, mime="application/pdf")
146
  st.markdown("#### Preview")