import streamlit as st
import os
import tempfile
import zipfile
import shutil
from pdf2image import convert_from_path
from ppt_converter import create_pptx_from_images, reconstruct_pptx_from_zip
# Page configuration
st.set_page_config(
page_title="PDF/圖片轉可編輯PPTX - 零成本在線版",
page_icon="📄",
layout="centered"
)
# Custom CSS for premium aesthetics (Dark Mode / Glassmorphism Feel)
st.markdown("""
""", unsafe_allow_html=True)
# Title and introduction
st.markdown("
📄 PDF / 圖片 轉 可編輯 PPTX
", unsafe_allow_html=True)
st.markdown("""
將無文字圖層的 AI 扁平簡報(如 NotebookLM)完美轉回 **「圖文分離、背景修復、可編輯」** 的 PowerPoint 檔!
""", unsafe_allow_html=True)
# Define Tabs
tab1, tab2 = st.tabs(["⚡ 在線極速轉換 (CPU)", "🚀 雲端高精轉換 (Colab GPU 匯入)"])
# -----------------
# Tab 1: Local CPU Mode
# -----------------
with tab1:
st.markdown("### ⚡ 在線極速轉換")
st.write("適合一般排版的 PDF 簡報。使用伺服器 CPU 進行 RapidOCR 辨識與 ONNX LaMa 去字修補,隱私安全,一鍵完成。")
uploaded_file = st.file_uploader("選擇上傳您的 PDF 或圖片檔案", type=['pdf', 'png', 'jpg', 'jpeg', 'webp'], key="cpu_uploader")
with st.expander("⚙️ 進階辨識設定"):
lang_options = ['ch_tra', 'en', 'ja', 'ko', 'ch_sim']
selected_langs = st.multiselect(
"選擇 OCR 辨識語言",
options=lang_options,
default=['ch_tra', 'en'],
help="選擇檔案中包含的語言,可大幅提升辨識準確度。"
)
high_accuracy = st.toggle(
"開啟高精度影像增強 (CLAHE)",
value=False,
help="開啟後會對圖片進行對比度增強,提升模糊與微小字體的辨識率,但會稍微增加處理時間。"
)
st.divider()
if uploaded_file is not None:
if st.button("🚀 開始線上轉換", key="cpu_convert_btn"):
if not selected_langs:
st.error("請至少選擇一種辨識語言!")
else:
progress_container = st.empty()
progress_bar = st.progress(0)
with st.spinner('處理中,正在進行 OCR 辨識與背景 AI 修復,請稍候...'):
try:
with tempfile.TemporaryDirectory() as temp_dir:
input_path = os.path.join(temp_dir, uploaded_file.name)
output_pptx_path = os.path.join(temp_dir, "output.pptx")
# Save uploaded file
with open(input_path, "wb") as f:
f.write(uploaded_file.getbuffer())
ext = os.path.splitext(input_path)[1].lower()
image_paths = []
if ext == ".pdf":
progress_container.info("正在解析 PDF 並轉換為高清圖片...")
images = convert_from_path(input_path)
total_p = len(images)
for idx, img in enumerate(images):
temp_img_path = os.path.join(temp_dir, f"page_{idx}.png")
img.save(temp_img_path, "PNG")
image_paths.append(temp_img_path)
progress_bar.progress(int((idx + 1) / total_p * 20)) # up to 20%
elif ext in [".png", ".jpg", ".jpeg", ".webp"]:
image_paths = [input_path]
progress_bar.progress(20)
# Callback for conversion progress
def update_conversion_progress(current, total):
percent = 20 + int((current / total) * 80)
progress_bar.progress(min(percent, 100))
progress_container.info(f"正在執行 AI 去字與重組簡報:第 {current} / {total} 頁...")
return True
# Convert
success = create_pptx_from_images(
image_paths,
output_pptx_path,
selected_langs,
high_accuracy=high_accuracy,
progress_callback=update_conversion_progress
)
if success:
# Read results
with open(output_pptx_path, "rb") as f:
pptx_data = f.read()
progress_container.success("🎉 轉換成功!請點擊下方按鈕下載 PPTX。")
progress_bar.progress(100)
st.download_button(
label="⬇️ 下載可編輯 PPTX 檔案",
data=pptx_data,
file_name=f"{os.path.splitext(uploaded_file.name)[0]}_editable.pptx",
mime="application/vnd.openxmlformats-officedocument.presentationml.presentation",
key="cpu_download"
)
else:
progress_container.error("轉換取消或失敗。")
except Exception as e:
progress_container.error(f"轉換過程中發生錯誤: {str(e)}")
st.exception(e)
# -----------------
# Tab 2: Colab GPU Import Mode
# -----------------
with tab2:
st.markdown("### 🚀 雲端高精轉換 (Google Colab GPU 分流)")
st.write("適用於多欄位、包含複雜圖表或超大檔案的簡報。此模式利用多模態大模型進行視覺定位,提供最極致的還原效果,且**完全免費**。")
st.markdown("""
💡 簡單三步驟完成高精度轉換:
1
點擊下方按鈕,在您自己的瀏覽器中打開 Google Colab 筆記本(會自動分配免費的 T4 GPU 算力):
2
在 Colab 中上傳您的 PDF 檔案,點擊「全部執行」,等待 1~3 分鐘後下載產生的 Pack.zip 壓縮包。
3
將下載的 Pack.zip 拖入下方上傳區,即可在一秒內拼裝並下載您的完美可編輯 PPTX!
""", unsafe_allow_html=True)
zip_file = st.file_uploader("請上傳 Colab 產出的 Pack.zip 壓縮包", type=['zip'], key="zip_uploader")
if zip_file is not None:
if st.button("🎨 一秒拼裝簡報", key="zip_assemble_btn"):
with st.spinner('正在解壓並映射座標...'):
try:
with tempfile.TemporaryDirectory() as temp_dir:
zip_path = os.path.join(temp_dir, zip_file.name)
output_pptx_path = os.path.join(temp_dir, "reconstructed.pptx")
# Save uploaded zip
with open(zip_path, "wb") as f:
f.write(zip_file.getbuffer())
# Reconstruct
success = reconstruct_pptx_from_zip(zip_path, output_pptx_path)
if success:
with open(output_pptx_path, "rb") as f:
pptx_data = f.read()
st.success("🎉 拼裝完成!請點擊下方按鈕下載 PPTX。")
st.download_button(
label="⬇️ 下載已拼裝 PPTX 檔案",
data=pptx_data,
file_name=f"{os.path.splitext(zip_file.name)[0]}_assembled.pptx",
mime="application/vnd.openxmlformats-officedocument.presentationml.presentation",
key="zip_download"
)
else:
st.error("組裝失敗,請確認上傳的 ZIP 封包格式是否正確。")
except Exception as e:
st.error(f"組裝過程中發生錯誤: {str(e)}")
st.exception(e)
# Footer
st.markdown("""
PDF/圖片轉可編輯PPTX系統 • 部署於 Hugging Face Spaces (CPU Basic) • 開源免運維版本
""", unsafe_allow_html=True)