ssh-AI commited on
Commit
4566ace
·
verified ·
1 Parent(s): 33474d5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -50
app.py CHANGED
@@ -6,42 +6,43 @@ import zipfile
6
  import os
7
  from fpdf import FPDF
8
 
9
- st.set_page_config(page_title="Smart Doc Scanner", page_icon="🖼️", layout="wide")
10
 
11
- # --- Resize image ---
12
- def resize_image(img, max_height=500):
13
  if img.height > max_height:
14
  ratio = max_height / img.height
15
- img = img.resize((int(img.width * ratio), max_height), Image.Resampling.LANCZOS)
16
  return img
17
 
18
- # --- Crop with slider ---
19
- def crop_sliders(img, key):
20
  w, h = img.size
21
  state = st.session_state
22
-
23
  if f"{key}_left" not in state:
24
  state[f"{key}_left"] = 0
25
  state[f"{key}_top"] = 0
26
  state[f"{key}_right"] = w
27
  state[f"{key}_bottom"] = h
28
 
29
- left = st.slider("Crop Left", 0, w - 10, state[f"{key}_left"], key=f"{key}_left_slider")
30
- top = st.slider("Crop Top", 0, h - 10, state[f"{key}_top"], key=f"{key}_top_slider")
31
- right = st.slider("Crop Right", left + 10, w, state[f"{key}_right"], key=f"{key}_right_slider")
32
- bottom = st.slider("Crop Bottom", top + 10, h, state[f"{key}_bottom"], key=f"{key}_bottom_slider")
 
 
 
 
 
 
33
 
34
- # Update stored values
35
  state[f"{key}_left"] = left
36
  state[f"{key}_top"] = top
37
  state[f"{key}_right"] = right
38
  state[f"{key}_bottom"] = bottom
39
-
40
  return (left, top, right, bottom)
41
 
42
- # --- App UI ---
43
  st.title("📄 Smart ID & Document Scanner")
44
- uploaded_files = st.file_uploader("📤 Upload Images", type=["jpg", "jpeg", "png"], accept_multiple_files=True)
45
 
46
  if uploaded_files:
47
  mode = st.radio("Mode", ["Normal Mode", "Advanced Mode (Edit Each)"])
@@ -51,22 +52,18 @@ if uploaded_files:
51
  key = f"img_{idx}"
52
  st.markdown(f"---\n### 🖼️ {file.name}")
53
  original = Image.open(file).convert("RGB")
54
- resized = resize_image(original)
55
-
56
  if f"original_{key}" not in st.session_state:
57
  st.session_state[f"original_{key}"] = original
58
  st.session_state[f"angle_{key}"] = 0
59
  st.session_state[f"enhance_{key}"] = False
60
 
61
  if mode == "Normal Mode":
62
- st.image(resized, use_container_width=True)
63
  processed_images.append(original)
64
  continue
65
 
66
- # --- Advanced Mode ---
67
- col_edit, col_preview = st.columns([1, 1.5])
68
-
69
- with col_edit:
70
  if st.button("🔁 Reset", key=f"reset_{key}"):
71
  st.session_state[f"angle_{key}"] = 0
72
  st.session_state[f"enhance_{key}"] = False
@@ -77,56 +74,59 @@ if uploaded_files:
77
 
78
  st.slider("🌀 Rotate", -180, 180, st.session_state[f"angle_{key}"], key=f"angle_{key}")
79
  st.checkbox("✨ Enhance", value=st.session_state[f"enhance_{key}"], key=f"enhance_{key}")
80
- st.markdown("#### ✂️ Crop")
81
- left, top, right, bottom = crop_sliders(st.session_state[f"original_{key}"], key)
82
 
83
  if st.button("✅ Save This Image", key=f"save_{key}"):
84
  st.session_state[f"final_{key}"] = st.session_state[f"preview_{key}"].copy()
85
- st.success("Image saved for export!")
 
 
 
 
 
86
 
87
- with col_preview:
88
- img = st.session_state[f"original_{key}"].copy()
89
- img = img.crop((left, top, right, bottom))
90
  if st.session_state[f"enhance_{key}"]:
91
- img = ImageEnhance.Contrast(img).enhance(1.5)
92
- img = ImageEnhance.Sharpness(img).enhance(2.0)
93
- if st.session_state[f"angle_{key}"] != 0:
94
- img = img.rotate(st.session_state[f"angle_{key}"], expand=True)
95
- st.session_state[f"preview_{key}"] = img
96
- st.image(img, caption="🎯 Preview", use_container_width=True)
 
 
 
97
 
98
- final = st.session_state.get(f"final_{key}", original)
99
- processed_images.append(final)
100
 
101
- # --- Export Section ---
102
  st.markdown("---")
103
  st.header("📥 Export Options")
104
  col1, col2 = st.columns(2)
105
 
106
  with col1:
107
- if st.button("📦 Download as ZIP"):
108
  zip_buffer = BytesIO()
109
- with zipfile.ZipFile(zip_buffer, "w") as zf:
110
  for i, img in enumerate(processed_images):
111
  buffer = BytesIO()
112
  img.save(buffer, format="PNG")
113
- zf.writestr(f"image_{i+1}.png", buffer.getvalue())
114
  zip_buffer.seek(0)
115
- st.download_button("📥 Download ZIP", zip_buffer, file_name="images.zip", mime="application/zip")
116
 
117
  with col2:
118
- if st.button("📄 Download as PDF"):
119
  pdf = FPDF()
120
- temp_files = []
121
  for img in processed_images:
122
  path = f"/tmp/{np.random.randint(0, 999999)}.jpg"
123
- img.save(path, format="JPEG")
124
  pdf.add_page()
125
  pdf.image(path, x=10, y=10, w=190)
126
- temp_files.append(path)
127
- out_path = "/tmp/output.pdf"
128
- pdf.output(out_path)
129
- with open(out_path, "rb") as f:
130
- st.download_button("📥 Download PDF", f, file_name="scanned.pdf", mime="application/pdf")
131
- for path in temp_files + [out_path]:
132
  os.remove(path)
 
6
  import os
7
  from fpdf import FPDF
8
 
9
+ st.set_page_config(page_title="Smart Doc Scanner", layout="wide")
10
 
11
+ # Resize for faster preview (non-destructive)
12
+ def resize_image(img, max_height=600):
13
  if img.height > max_height:
14
  ratio = max_height / img.height
15
+ return img.resize((int(img.width * ratio), max_height), Image.Resampling.LANCZOS)
16
  return img
17
 
18
+ def crop_sliders(img, key, compact=False):
 
19
  w, h = img.size
20
  state = st.session_state
 
21
  if f"{key}_left" not in state:
22
  state[f"{key}_left"] = 0
23
  state[f"{key}_top"] = 0
24
  state[f"{key}_right"] = w
25
  state[f"{key}_bottom"] = h
26
 
27
+ slider_args = {"label_visibility": "visible"} if compact else {}
28
+ with st.container():
29
+ st.markdown("#### ✂️ Crop", help=None)
30
+ col1, col2 = st.columns(2)
31
+ with col1:
32
+ left = st.slider("Crop Left", 0, w - 10, state[f"{key}_left"], key=f"{key}_left_slider", **slider_args)
33
+ right = st.slider("Crop Right", left + 10, w, state[f"{key}_right"], key=f"{key}_right_slider", **slider_args)
34
+ with col2:
35
+ top = st.slider("Crop Top", 0, h - 10, state[f"{key}_top"], key=f"{key}_top_slider", **slider_args)
36
+ bottom = st.slider("Crop Bottom", top + 10, h, state[f"{key}_bottom"], key=f"{key}_bottom_slider", **slider_args)
37
 
 
38
  state[f"{key}_left"] = left
39
  state[f"{key}_top"] = top
40
  state[f"{key}_right"] = right
41
  state[f"{key}_bottom"] = bottom
 
42
  return (left, top, right, bottom)
43
 
 
44
  st.title("📄 Smart ID & Document Scanner")
45
+ uploaded_files = st.file_uploader("📤 Upload Images", type=["png", "jpg", "jpeg"], accept_multiple_files=True)
46
 
47
  if uploaded_files:
48
  mode = st.radio("Mode", ["Normal Mode", "Advanced Mode (Edit Each)"])
 
52
  key = f"img_{idx}"
53
  st.markdown(f"---\n### 🖼️ {file.name}")
54
  original = Image.open(file).convert("RGB")
 
 
55
  if f"original_{key}" not in st.session_state:
56
  st.session_state[f"original_{key}"] = original
57
  st.session_state[f"angle_{key}"] = 0
58
  st.session_state[f"enhance_{key}"] = False
59
 
60
  if mode == "Normal Mode":
61
+ st.image(resize_image(original), use_container_width=True)
62
  processed_images.append(original)
63
  continue
64
 
65
+ col1, col2 = st.columns([1, 1.5])
66
+ with col1:
 
 
67
  if st.button("🔁 Reset", key=f"reset_{key}"):
68
  st.session_state[f"angle_{key}"] = 0
69
  st.session_state[f"enhance_{key}"] = False
 
74
 
75
  st.slider("🌀 Rotate", -180, 180, st.session_state[f"angle_{key}"], key=f"angle_{key}")
76
  st.checkbox("✨ Enhance", value=st.session_state[f"enhance_{key}"], key=f"enhance_{key}")
77
+ left, top, right, bottom = crop_sliders(original, key, compact=True)
 
78
 
79
  if st.button("✅ Save This Image", key=f"save_{key}"):
80
  st.session_state[f"final_{key}"] = st.session_state[f"preview_{key}"].copy()
81
+ st.success("Saved for export!")
82
+
83
+ with col2:
84
+ preview = st.session_state[f"original_{key}"].copy()
85
+ preview = preview.crop((left, top, right, bottom))
86
+ preview = resize_image(preview) # faster rendering
87
 
 
 
 
88
  if st.session_state[f"enhance_{key}"]:
89
+ preview = ImageEnhance.Contrast(preview).enhance(1.5)
90
+ preview = ImageEnhance.Sharpness(preview).enhance(2.0)
91
+
92
+ angle = st.session_state[f"angle_{key}"]
93
+ if angle != 0:
94
+ preview = preview.rotate(angle, expand=True)
95
+
96
+ st.session_state[f"preview_{key}"] = preview
97
+ st.image(preview, caption="🎯 Preview", use_container_width=True)
98
 
99
+ final_img = st.session_state.get(f"final_{key}", original)
100
+ processed_images.append(final_img)
101
 
 
102
  st.markdown("---")
103
  st.header("📥 Export Options")
104
  col1, col2 = st.columns(2)
105
 
106
  with col1:
107
+ if st.button("📦 Download ZIP"):
108
  zip_buffer = BytesIO()
109
+ with zipfile.ZipFile(zip_buffer, "w") as zipf:
110
  for i, img in enumerate(processed_images):
111
  buffer = BytesIO()
112
  img.save(buffer, format="PNG")
113
+ zipf.writestr(f"image_{i+1}.png", buffer.getvalue())
114
  zip_buffer.seek(0)
115
+ st.download_button("📥 Download ZIP", zip_buffer, "images.zip", mime="application/zip")
116
 
117
  with col2:
118
+ if st.button("📄 Download PDF"):
119
  pdf = FPDF()
120
+ tmp_files = []
121
  for img in processed_images:
122
  path = f"/tmp/{np.random.randint(0, 999999)}.jpg"
123
+ img.save(path, "JPEG")
124
  pdf.add_page()
125
  pdf.image(path, x=10, y=10, w=190)
126
+ tmp_files.append(path)
127
+ output_pdf = "/tmp/output.pdf"
128
+ pdf.output(output_pdf)
129
+ with open(output_pdf, "rb") as f:
130
+ st.download_button("📥 Download PDF", f, "scanned.pdf", "application/pdf")
131
+ for path in tmp_files + [output_pdf]:
132
  os.remove(path)