ssh-AI commited on
Commit
f6491d9
·
verified ·
1 Parent(s): bfad80e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +114 -93
app.py CHANGED
@@ -1,113 +1,134 @@
1
  import streamlit as st
2
- from PIL import Image, ImageEnhance
3
- from io import BytesIO
4
- import os
5
- import cv2
6
  import numpy as np
7
- from fpdf import FPDF
8
- from streamlit_cropper import st_cropper
9
  import zipfile
 
 
 
10
 
11
- # --- Set Page Config ---
12
- st.set_page_config(page_title="Smart ID Scanner", page_icon="🪪", layout="centered")
 
 
 
 
13
 
14
- # --- Add Background Style ---
15
- page_bg_img = """
16
  <style>
17
- body {
18
- background: linear-gradient(to right, #ece9e6, #ffffff);
 
 
 
 
 
 
 
19
  }
20
  .stButton>button {
21
  color: white;
22
- background-color: #4CAF50;
23
- border: none;
24
- padding: 0.5em 1em;
25
- border-radius: 5px;
26
- }
27
- .stHeader, .stText, .stMarkdown {
28
- color: #333333;
29
  }
30
  </style>
31
- """
 
32
  st.markdown(page_bg_img, unsafe_allow_html=True)
33
 
34
- # --- App Heading ---
35
- st.markdown("<h1 style='text-align: center; color: #2E86C1;'>📄 Smart ID & Document Scanner</h1>", unsafe_allow_html=True)
36
- st.write("---")
37
 
38
- # --- Upload Images ---
39
- uploaded_files = st.file_uploader("Upload ID/Document Images 📷 (All formats supported)", type=['png', 'jpg', 'jpeg'], accept_multiple_files=True)
 
 
 
 
40
 
41
  if uploaded_files:
42
- cropped_images = []
 
 
 
 
 
 
 
43
  for uploaded_file in uploaded_files:
44
  image = Image.open(uploaded_file).convert("RGB")
45
-
46
- st.subheader(f"Crop & Adjust: {uploaded_file.name}")
47
 
48
- # --- Free style manual crop ---
49
- crop_box = st_cropper(image, realtime_update=True, box_color='#FF9900', aspect_ratio=None)
50
- cropped_img = crop_box.copy()
51
-
52
- # --- Before / After Preview ---
53
- st.write("### Preview:")
54
- col1, col2 = st.columns(2)
55
- with col1:
56
- st.image(image, caption="Original", use_container_width=True)
57
- with col2:
58
- st.image(cropped_img, caption="Cropped", use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
- # --- Enhancement Option ---
61
- if st.button(f"Enhance Image: {uploaded_file.name}"):
62
- with st.spinner('Enhancing...'):
63
- enhancer = ImageEnhance.Contrast(cropped_img)
64
- cropped_img = enhancer.enhance(1.5)
65
- sharpener = ImageEnhance.Sharpness(cropped_img)
66
- cropped_img = sharpener.enhance(2.0)
67
- st.success("Enhanced Successfully!")
68
- st.image(cropped_img, caption="Enhanced", use_container_width=True)
69
-
70
- cropped_images.append(cropped_img)
71
-
72
- st.write("---")
73
-
74
- # --- Download Options ---
75
- col1, col2 = st.columns(2)
76
-
77
- # Save as PDF
78
- with col1:
79
- if st.button("Generate PDF 📄"):
80
- with st.spinner('Generating PDF...'):
81
- pdf = FPDF()
82
- temp_image_paths = []
83
- for img in cropped_images:
84
- temp_path = f"/tmp/{np.random.randint(0,10000)}.jpg"
85
- img.save(temp_path, format="JPEG")
86
- temp_image_paths.append(temp_path)
87
- pdf.add_page()
88
- pdf.image(temp_path, x=10, y=10, w=190)
89
-
90
- pdf_output_path = "/tmp/scanned_document.pdf"
91
- pdf.output(pdf_output_path)
92
-
93
- with open(pdf_output_path, "rb") as f:
94
- st.download_button(label="📥 Download PDF", data=f, file_name="scanned_document.pdf", mime="application/pdf")
95
-
96
- # Clean up
97
- for path in temp_image_paths:
98
- os.remove(path)
99
- os.remove(pdf_output_path)
100
-
101
- # Save all as Images in ZIP
102
- with col2:
103
- if st.button("Save All as Images 📷"):
104
- with st.spinner('Saving Images...'):
105
- zip_buffer = BytesIO()
106
- with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED) as zip_file:
107
- for idx, img in enumerate(cropped_images):
108
- img_bytes = BytesIO()
109
- img.save(img_bytes, format='PNG')
110
- img_bytes.seek(0)
111
- zip_file.writestr(f"scanned_image_{idx+1}.png", img_bytes.read())
112
- zip_buffer.seek(0)
113
- st.download_button(label="📥 Download All Images (ZIP)", data=zip_buffer, file_name="scanned_images.zip", mime="application/zip")
 
1
  import streamlit as st
2
+ from PIL import Image, ImageEnhance, ImageOps
 
 
 
3
  import numpy as np
4
+ import io
 
5
  import zipfile
6
+ import os
7
+ import datetime
8
+ import cv2
9
 
10
+ # Set page configuration
11
+ st.set_page_config(
12
+ page_title="📄 Smart Doc Scanner",
13
+ page_icon="🖼️",
14
+ layout="centered",
15
+ )
16
 
17
+ # Custom CSS for background and buttons
18
+ page_bg_img = '''
19
  <style>
20
+ .stApp {
21
+ background-image: url("https://images.unsplash.com/photo-1524995997946-a1c2e315a42f");
22
+ background-size: cover;
23
+ background-position: center;
24
+ }
25
+ h1 {
26
+ color: #ffffff;
27
+ text-align: center;
28
+ text-shadow: 2px 2px #000000;
29
  }
30
  .stButton>button {
31
  color: white;
32
+ background-color: #0078FF;
33
+ border-radius: 10px;
 
 
 
 
 
34
  }
35
  </style>
36
+ '''
37
+
38
  st.markdown(page_bg_img, unsafe_allow_html=True)
39
 
40
+ st.markdown("<h1>📄 Smart Doc Scanner</h1>", unsafe_allow_html=True)
 
 
41
 
42
+ # Upload multiple images
43
+ uploaded_files = st.file_uploader(
44
+ "Upload Document Images (JPEG, PNG, JPG)",
45
+ type=["jpg", "jpeg", "png"],
46
+ accept_multiple_files=True
47
+ )
48
 
49
  if uploaded_files:
50
+ enhance_option = st.checkbox("✨ Enhance Images (Scanner Effect)", value=True)
51
+ manual_crop = st.checkbox("✂️ Manual Crop")
52
+ auto_crop = st.checkbox("⚡ Auto Crop Background")
53
+ rotate_left = st.button("⏪ Rotate Left")
54
+ rotate_right = st.button("⏩ Rotate Right")
55
+
56
+ processed_images = []
57
+
58
  for uploaded_file in uploaded_files:
59
  image = Image.open(uploaded_file).convert("RGB")
 
 
60
 
61
+ # Rotate manually if needed
62
+ if rotate_left:
63
+ image = image.rotate(90, expand=True)
64
+ if rotate_right:
65
+ image = image.rotate(-90, expand=True)
66
+
67
+ # Auto-crop (border removal)
68
+ if auto_crop:
69
+ open_cv_image = np.array(image)
70
+ gray = cv2.cvtColor(open_cv_image, cv2.COLOR_RGB2GRAY)
71
+ _, thresh = cv2.threshold(gray, 250, 255, cv2.THRESH_BINARY_INV)
72
+ contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
73
+
74
+ if contours:
75
+ x, y, w, h = cv2.boundingRect(contours[0])
76
+ open_cv_image = open_cv_image[y:y+h, x:x+w]
77
+ image = Image.fromarray(open_cv_image)
78
+
79
+ # Manual crop if user wants
80
+ if manual_crop:
81
+ st.write("Adjust cropping manually below:")
82
+ cropped_image = st.image(image, use_container_width=True)
83
+ st.info("Manual cropping not yet interactive (advanced version can be added later).")
84
+
85
+ # Enhance image
86
+ if enhance_option:
87
+ enhancer = ImageEnhance.Contrast(image)
88
+ image = enhancer.enhance(1.5)
89
+ sharpener = ImageEnhance.Sharpness(image)
90
+ image = sharpener.enhance(2.0)
91
+
92
+ # Display final image
93
+ st.image(image, caption="Processed Image", use_container_width=True)
94
+
95
+ processed_images.append(image)
96
+
97
+ if processed_images:
98
+ # Download processed images as zip
99
+ zip_buffer = io.BytesIO()
100
+ with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED) as zf:
101
+ for idx, img in enumerate(processed_images):
102
+ img_byte_arr = io.BytesIO()
103
+ img.save(img_byte_arr, format='JPEG')
104
+ zf.writestr(f"processed_image_{idx+1}.jpg", img_byte_arr.getvalue())
105
 
106
+ st.download_button(
107
+ label="📥 Download All Images (ZIP)",
108
+ data=zip_buffer.getvalue(),
109
+ file_name=f"processed_images_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.zip",
110
+ mime="application/zip"
111
+ )
112
+
113
+ # Create PDF
114
+ from fpdf import FPDF
115
+ pdf = FPDF()
116
+ for img in processed_images:
117
+ img_path = "temp_img.jpg"
118
+ img.save(img_path)
119
+ width, height = img.size
120
+ pdf.add_page()
121
+ pdf.image(img_path, x=0, y=0, w=210, h=297)
122
+ os.remove(img_path)
123
+
124
+ pdf_output_path = f"scanned_document_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
125
+ pdf.output(pdf_output_path)
126
+
127
+ with open(pdf_output_path, "rb") as f:
128
+ st.download_button(
129
+ label="📄 Download as PDF",
130
+ data=f,
131
+ file_name=pdf_output_path,
132
+ mime="application/pdf"
133
+ )
134
+ os.remove(pdf_output_path)