Spaces:
Sleeping
Sleeping
| # app.py | |
| """ | |
| Main Streamlit application file for the PDF to Single Image Converter. | |
| Coordinates the UI, file handling, and calls the processing logic. | |
| """ | |
| import streamlit as st | |
| import tempfile | |
| import os | |
| import time | |
| from typing import Optional | |
| # Import functions from our modules | |
| from pdf_processor import pdf_to_single_image | |
| from ui_components import ( | |
| render_sidebar, | |
| display_file_details, | |
| display_results, | |
| render_initial_info, | |
| display_installation_info | |
| ) | |
| # --- Page Configuration --- | |
| st.set_page_config( | |
| page_title="PDF to Single Image Converter", | |
| page_icon="π", | |
| layout="centered", # Can be "wide" or "centered" | |
| initial_sidebar_state="expanded" # Keep sidebar open initially | |
| ) | |
| # --- Main Application --- | |
| st.title("π PDF to Single Image Converter") | |
| st.markdown("Upload a multi-page PDF and convert it into a single, tall image file (PNG or JPG).") | |
| # --- Sidebar --- | |
| dpi_setting, format_setting = render_sidebar() | |
| # --- File Upload --- | |
| # Use a key for the file uploader to potentially reset it later if needed | |
| uploaded_file: Optional[st.runtime.uploaded_file_manager.UploadedFile] = st.file_uploader( | |
| "Choose a PDF file", type="pdf", key="pdf_uploader" | |
| ) | |
| # --- Processing Logic --- | |
| if uploaded_file is not None: | |
| # Display details of the uploaded file | |
| display_file_details(uploaded_file) | |
| # Use a temporary file for robust handling by PyMuPDF | |
| temp_pdf_path: Optional[str] = None | |
| try: | |
| # Create a temporary file to store the uploaded PDF content | |
| with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_file: | |
| tmp_file.write(uploaded_file.getvalue()) | |
| temp_pdf_path = tmp_file.name # Store the path | |
| # Add a button to trigger the conversion | |
| if st.button(f"π Convert to {format_setting}", key="convert_button"): | |
| if temp_pdf_path: # Ensure temp path is valid | |
| try: | |
| # Show a spinner during processing | |
| with st.spinner(f"Converting PDF to {format_setting} at {dpi_setting} DPI... Please wait."): | |
| start_time = time.time() | |
| # Call the core conversion function from pdf_processor | |
| img_buffer = pdf_to_single_image( | |
| pdf_path=temp_pdf_path, | |
| output_format=format_setting, | |
| dpi=dpi_setting | |
| ) | |
| processing_time = time.time() - start_time | |
| # Prepare output filename | |
| base_filename = os.path.splitext(uploaded_file.name)[0] | |
| output_filename = f"{base_filename}_converted.{format_setting.lower()}" | |
| # Display the results (download button, preview) | |
| if img_buffer.getbuffer().nbytes > 0: # Check if buffer has content | |
| display_results( | |
| img_buffer=img_buffer, | |
| output_filename=output_filename, | |
| output_format=format_setting, | |
| processing_time=processing_time | |
| ) | |
| else: | |
| st.error("Conversion resulted in an empty image. Please check the PDF file.") | |
| except Exception as e: | |
| st.error(f"β An error occurred during conversion:") | |
| st.exception(e) # Displays the full traceback for debugging | |
| finally: | |
| # --- Cleanup --- | |
| # Ensure the temporary file is deleted after processing or if an error occurs | |
| if temp_pdf_path and os.path.exists(temp_pdf_path): | |
| try: | |
| os.unlink(temp_pdf_path) | |
| # st.write(f"Temporary file {temp_pdf_path} deleted.") # Optional debug message | |
| except OSError as e: | |
| st.warning(f"Could not delete temporary file {temp_pdf_path}: {e}") | |
| else: | |
| # Show initial instructions if no file is uploaded | |
| render_initial_info() | |
| # --- Footer / Installation Info --- | |
| display_installation_info() | |