Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| from pypdf import PdfWriter, PdfReader | |
| from PIL import Image | |
| import io | |
| # --- PAGE CONFIGURATION --- | |
| st.set_page_config( | |
| page_title="PDF & Image Toolkit", | |
| page_icon="π", | |
| layout="centered", | |
| ) | |
| # --- HELPER FUNCTIONS --- | |
| def merge_pdfs(uploaded_files): | |
| """Merges multiple PDF files into one.""" | |
| merger = PdfWriter() | |
| for pdf_file in uploaded_files: | |
| # pypdf needs a file object, so we wrap the uploaded bytes in BytesIO | |
| merger.append(io.BytesIO(pdf_file.getvalue())) | |
| # Write the merged PDF to a BytesIO object in memory | |
| output_buffer = io.BytesIO() | |
| merger.write(output_buffer) | |
| merger.close() | |
| return output_buffer.getvalue() | |
| def compress_pdf(uploaded_file): | |
| """Performs basic compression on a PDF file.""" | |
| reader = PdfReader(io.BytesIO(uploaded_file.getvalue())) | |
| writer = PdfWriter() | |
| for page in reader.pages: | |
| # This is a basic form of compression | |
| page.compress_content_streams() | |
| writer.add_page(page) | |
| # Write the compressed PDF to a BytesIO object | |
| output_buffer = io.BytesIO() | |
| writer.write(output_buffer) | |
| writer.close() | |
| return output_buffer.getvalue() | |
| def images_to_pdf(uploaded_files): | |
| """Converts a list of images to a single PDF.""" | |
| images = [] | |
| for img_file in uploaded_files: | |
| img = Image.open(io.BytesIO(img_file.getvalue())) | |
| # Convert to RGB to avoid issues with different image modes (e.g., RGBA, P) | |
| if img.mode == 'RGBA' or img.mode == 'P': | |
| img = img.convert('RGB') | |
| images.append(img) | |
| if not images: | |
| return None | |
| # Save the images as a PDF to a BytesIO object | |
| output_buffer = io.BytesIO() | |
| images[0].save( | |
| output_buffer, | |
| "PDF" , | |
| resolution=100.0, | |
| save_all=True, | |
| append_images=images[1:] | |
| ) | |
| return output_buffer.getvalue() | |
| # --- STREAMLIT UI --- | |
| st.title("π PDF & Image Toolkit") | |
| st.write("A simple web app to manage your documents. All processing is done in your browser and on the server, and your files are not saved.") | |
| # --- SIDEBAR FOR TOOL SELECTION --- | |
| with st.sidebar: | |
| st.header("Tools") | |
| tool_choice = st.radio( | |
| "Select a tool:", | |
| ("Merge PDFs", "Compress PDF", "Convert Images to PDF") | |
| ) | |
| # --- MAIN PAGE CONTENT --- | |
| if tool_choice == "Merge PDFs": | |
| st.subheader("Merge Multiple PDF Files") | |
| st.write("Upload two or more PDF files to combine them into a single document.") | |
| uploaded_pdfs = st.file_uploader( | |
| "Upload PDF files", | |
| type="pdf", | |
| accept_multiple_files=True, | |
| key="pdf_merger" | |
| ) | |
| if st.button("Merge PDFs") and uploaded_pdfs: | |
| if len(uploaded_pdfs) < 2: | |
| st.warning("Please upload at least two PDF files to merge.") | |
| else: | |
| with st.spinner("Merging..."): | |
| merged_pdf_bytes = merge_pdfs(uploaded_pdfs) | |
| st.success("PDFs merged successfully!") | |
| st.download_button( | |
| label="Download Merged PDF", | |
| data=merged_pdf_bytes, | |
| file_name="merged_document.pdf", | |
| mime="application/pdf", | |
| ) | |
| elif tool_choice == "Compress PDF": | |
| st.subheader("Compress a PDF File") | |
| st.info("This tool performs basic optimization. It may not significantly reduce the size of all PDFs, especially those that are already optimized or text-heavy.") | |
| uploaded_pdf = st.file_uploader( | |
| "Upload a PDF file", | |
| type="pdf", | |
| accept_multiple_files=False, | |
| key="pdf_compressor" | |
| ) | |
| if st.button("Compress PDF") and uploaded_pdf: | |
| with st.spinner("Compressing..."): | |
| compressed_pdf_bytes = compress_pdf(uploaded_pdf) | |
| original_size = uploaded_pdf.size | |
| compressed_size = len(compressed_pdf_bytes) | |
| reduction = ((original_size - compressed_size) / original_size) * 100 | |
| st.success(f"Compression complete! Size reduced by {reduction:.2f}%.") | |
| st.download_button( | |
| label="Download Compressed PDF", | |
| data=compressed_pdf_bytes, | |
| file_name="compressed_document.pdf", | |
| mime="application/pdf", | |
| ) | |
| elif tool_choice == "Convert Images to PDF": | |
| st.subheader("Convert Images to a Single PDF") | |
| st.write("Upload one or more images (JPG, PNG) to combine them into a PDF.") | |
| uploaded_images = st.file_uploader( | |
| "Upload image files", | |
| type=["png", "jpg", "jpeg"], | |
| accept_multiple_files=True, | |
| key="img_converter" | |
| ) | |
| if st.button("Convert to PDF") and uploaded_images: | |
| with st.spinner("Converting..."): | |
| pdf_from_images_bytes = images_to_pdf(uploaded_images) | |
| st.success("Images converted to PDF successfully!") | |
| st.download_button( | |
| label="Download PDF", | |
| data=pdf_from_images_bytes, | |
| file_name="images_converted.pdf", | |
| mime="application/pdf", | |
| ) | |
| st.sidebar.markdown("---") | |
| st.sidebar.info("App built with [Streamlit](https://streamlit.io) and hosted on [Hugging Face Spaces](https://huggingface.co/spaces).") | |