Spaces:
Sleeping
Sleeping
File size: 12,304 Bytes
f996a9b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | 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("""
<style>
/* Main Background & Fonts */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap');
.stApp {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
/* Title Style */
.title-container {
text-align: center;
padding: 1.5rem 0;
margin-bottom: 2rem;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
/* Tab buttons and cards */
.css-1n76uvr {
gap: 0rem;
}
div.stButton > button:first-child {
background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
color: white;
border: none;
padding: 0.6rem 2rem;
border-radius: 8px;
font-weight: 600;
letter-spacing: 0.5px;
transition: all 0.3s ease;
box-shadow: 0 4px 12px rgba(124, 58, 237, 0.3);
}
div.stButton > button:first-child:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(124, 58, 237, 0.4);
background: linear-gradient(135deg, #4338ca 0%, #6d28d9 100%);
}
.card {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 12px;
padding: 1.5rem;
margin-bottom: 1.5rem;
}
/* Steps styling for Colab */
.step-number {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border-radius: 50%;
background-color: #4f46e5;
color: white;
font-weight: bold;
margin-right: 8px;
}
.colab-btn {
display: inline-block;
padding: 0.5rem 1.2rem;
background-color: #f9ab00;
color: #1e1e1e !important;
border-radius: 6px;
font-weight: bold;
text-decoration: none;
transition: background-color 0.3s;
margin: 10px 0;
box-shadow: 0 4px 10px rgba(249, 171, 0, 0.2);
}
.colab-btn:hover {
background-color: #e39a00;
}
</style>
""", unsafe_allow_html=True)
# Title and introduction
st.markdown("<div class='title-container'><h1>📄 PDF / 圖片 轉 可編輯 PPTX</h1></div>", unsafe_allow_html=True)
st.markdown("""
<div style='text-align: center; margin-top: -20px; margin-bottom: 30px; color: #6b7280; font-size: 1.05rem;'>
將無文字圖層的 AI 扁平簡報(如 NotebookLM)完美轉回 **「圖文分離、背景修復、可編輯」** 的 PowerPoint 檔!
</div>
""", 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("""
<div class="card">
<h4 style="margin-top:0;">💡 簡單三步驟完成高精度轉換:</h4>
<div style="margin-bottom:10px;">
<span class="step-number">1</span>
點擊下方按鈕,在您自己的瀏覽器中打開 Google Colab 筆記本(會自動分配免費的 T4 GPU 算力):
</div>
<div style="text-align:center;">
<a href="https://colab.research.google.com/" target="_blank" class="colab-btn">💻 開啟 Google Colab 轉換腳本</a>
</div>
<div style="margin-bottom:10px; margin-top:10px;">
<span class="step-number">2</span>
在 Colab 中上傳您的 PDF 檔案,點擊「全部執行」,等待 1~3 分鐘後下載產生的 <code>Pack.zip</code> 壓縮包。
</div>
<div>
<span class="step-number">3</span>
將下載的 <code>Pack.zip</code> 拖入下方上傳區,即可在一秒內拼裝並下載您的完美可編輯 PPTX!
</div>
</div>
""", 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("""
<div style='text-align: center; margin-top: 50px; font-size: 0.8rem; color: #9ca3af; border-top: 1px solid rgba(255,255,255,0.05); padding-top: 15px;'>
PDF/圖片轉可編輯PPTX系統 • 部署於 Hugging Face Spaces (CPU Basic) • 開源免運維版本
</div>
""", unsafe_allow_html=True)
|