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() | |