STLooo commited on
Commit
ea494fa
·
verified ·
1 Parent(s): 5d54389

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -39
app.py CHANGED
@@ -2,9 +2,8 @@ import os, cv2, zipfile, gc, gradio as gr
2
  import numpy as np
3
  import fitz # PyMuPDF
4
  from PIL import Image
5
- from io import BytesIO
6
 
7
- # 數設定
8
  OUTPUT_DIR = "output"
9
  ZIP_PATH = os.path.join(OUTPUT_DIR, "results.zip")
10
  BG_PATH = "background.jpg"
@@ -12,28 +11,24 @@ TARGET_WIDTH, TARGET_HEIGHT = 2133, 1200
12
  POS1 = (1032, 0)
13
  POS2 = (4666, 0)
14
 
15
- # 檢查資料夾權限
16
  def ensure_dir(path):
17
  os.makedirs(path, exist_ok=True)
18
  if not os.access(path, os.W_OK):
19
- raise RuntimeError(f"❌ 無法寫入:{path}")
20
  ensure_dir(OUTPUT_DIR)
21
 
22
- # PDF 轉圖像(記憶體內處理)
23
- def pdf_to_images(pdf_file, start_page=None, end_page=None):
24
- import numpy as np
25
  images = []
26
- with fitz.open(pdf_file.name) as doc:
27
- total_pages = len(doc)
28
- start = max(0, (start_page or 1) - 1)
29
- end = min(end_page or total_pages, total_pages)
30
- for page_num in range(start, end):
31
- pix = doc[page_num].get_pixmap(matrix=fitz.Matrix(2, 2), colorspace=fitz.csRGB)
32
- img = np.frombuffer(pix.samples, dtype=np.uint8).reshape((pix.height, pix.width, 3))
33
- images.append(img)
34
  return images
35
 
36
- # 圖像合成功能
37
  def overlay_image(bg, fg_img, x, y):
38
  fg = cv2.resize(np.array(fg_img), (TARGET_WIDTH, TARGET_HEIGHT), interpolation=cv2.INTER_AREA)
39
  if fg.shape[2] == 4:
@@ -46,12 +41,12 @@ def overlay_image(bg, fg_img, x, y):
46
  bg[y:y+TARGET_HEIGHT, x:x+TARGET_WIDTH] = fg
47
  return bg
48
 
49
- # 合成 + 輸出 ZIP
50
  def process_and_combine(images, prefix):
51
  bg = cv2.imread(BG_PATH)
52
  if bg is None:
53
- raise gr.Error("❌ 無法讀取 background.jpg")
54
-
55
  for f in os.listdir(OUTPUT_DIR):
56
  if f.endswith(".jpg"):
57
  os.remove(os.path.join(OUTPUT_DIR, f))
@@ -63,48 +58,51 @@ def process_and_combine(images, prefix):
63
  output_path = os.path.join(OUTPUT_DIR, f"{prefix}{i:03d}.jpg")
64
  cv2.imwrite(output_path, combined)
65
  results.append((output_path, f"{prefix}{i:03d}"))
 
66
  if i % 10 == 0:
67
  gc.collect()
68
 
69
  if not results:
70
- raise gr.Error("⚠️ 沒有生圖片")
71
 
72
  with zipfile.ZipFile(ZIP_PATH, "w", zipfile.ZIP_DEFLATED) as zipf:
73
  for f in sorted(os.listdir(OUTPUT_DIR)):
74
  if f.endswith(".jpg"):
75
  zipf.write(os.path.join(OUTPUT_DIR, f), arcname=f)
76
- return results, ZIP_PATH, f"✅ 共合成 {len(results)} 張圖,已打包 ZIP"
77
 
78
- # 主流程
 
 
79
  def process_inputs(files, prefix):
80
  prefix = prefix.strip() or "result_"
81
  images = []
 
82
  for file in files:
83
  name = file.name.lower()
84
  if name.endswith(".pdf"):
85
  images.extend(pdf_to_images(file))
86
- elif name.endswith((".png", ".jpg", ".jpeg")):
87
  img = Image.open(file).convert("RGBA")
88
  images.append(img)
89
  else:
90
  raise gr.Error(f"不支援的檔案格式:{name}")
91
  return process_and_combine(images, prefix)
92
 
93
- # Gradio UI
94
- with gr.Blocks(title="PDF合成工具") as demo:
95
- gr.Markdown("### 📄🖼️ PDF / 圖片雙輸入合成工具(背景固定為 7872x1200)")
96
-
97
- with gr.Row():
98
- files = gr.Files(label="📎 上傳 PDF 或圖片", file_types=[".pdf", ".png", ".jpg", ".jpeg"])
99
- prefix = gr.Textbox(label="檔名前綴(可選)", placeholder="例如:poster_")
100
- run_btn = gr.Button("🚀 開始合成", variant="primary")
101
-
102
- with gr.Row():
103
- gallery = gr.Gallery(label="🖼️ 預覽", columns=3, height="auto")
104
- zip_file = gr.File(label="⬇️ 下載 ZIP")
105
- log = gr.Textbox(label="📄 日誌", interactive=False)
106
-
107
- run_btn.click(fn=process_inputs, inputs=[files, prefix], outputs=[gallery, zip_file, log])
108
 
109
  if __name__ == "__main__":
110
- demo.launch()
 
2
  import numpy as np
3
  import fitz # PyMuPDF
4
  from PIL import Image
 
5
 
6
+ # 數設定
7
  OUTPUT_DIR = "output"
8
  ZIP_PATH = os.path.join(OUTPUT_DIR, "results.zip")
9
  BG_PATH = "background.jpg"
 
11
  POS1 = (1032, 0)
12
  POS2 = (4666, 0)
13
 
14
+ # 確保目錄可寫入
15
  def ensure_dir(path):
16
  os.makedirs(path, exist_ok=True)
17
  if not os.access(path, os.W_OK):
18
+ raise RuntimeError(f"❌ 無法寫入資料夾:{path}")
19
  ensure_dir(OUTPUT_DIR)
20
 
21
+ # PDF轉圖
22
+ def pdf_to_images(file):
 
23
  images = []
24
+ doc = fitz.open(file.name)
25
+ for page in doc:
26
+ pix = page.get_pixmap(matrix=fitz.Matrix(2, 2), colorspace=fitz.csRGB)
27
+ img = np.frombuffer(pix.samples, dtype=np.uint8).reshape(pix.height, pix.width, 3)
28
+ images.append(img)
 
 
 
29
  return images
30
 
31
+ # 合成
32
  def overlay_image(bg, fg_img, x, y):
33
  fg = cv2.resize(np.array(fg_img), (TARGET_WIDTH, TARGET_HEIGHT), interpolation=cv2.INTER_AREA)
34
  if fg.shape[2] == 4:
 
41
  bg[y:y+TARGET_HEIGHT, x:x+TARGET_WIDTH] = fg
42
  return bg
43
 
44
+ # 合成輸出
45
  def process_and_combine(images, prefix):
46
  bg = cv2.imread(BG_PATH)
47
  if bg is None:
48
+ raise gr.Error("❌ 找不到 background.jpg")
49
+
50
  for f in os.listdir(OUTPUT_DIR):
51
  if f.endswith(".jpg"):
52
  os.remove(os.path.join(OUTPUT_DIR, f))
 
58
  output_path = os.path.join(OUTPUT_DIR, f"{prefix}{i:03d}.jpg")
59
  cv2.imwrite(output_path, combined)
60
  results.append((output_path, f"{prefix}{i:03d}"))
61
+
62
  if i % 10 == 0:
63
  gc.collect()
64
 
65
  if not results:
66
+ raise gr.Error("⚠️ 沒有生圖片")
67
 
68
  with zipfile.ZipFile(ZIP_PATH, "w", zipfile.ZIP_DEFLATED) as zipf:
69
  for f in sorted(os.listdir(OUTPUT_DIR)):
70
  if f.endswith(".jpg"):
71
  zipf.write(os.path.join(OUTPUT_DIR, f), arcname=f)
 
72
 
73
+ return results, ZIP_PATH, f"✅ 合成完成,共 {len(results)} 張圖片"
74
+
75
+ # 主函數
76
  def process_inputs(files, prefix):
77
  prefix = prefix.strip() or "result_"
78
  images = []
79
+
80
  for file in files:
81
  name = file.name.lower()
82
  if name.endswith(".pdf"):
83
  images.extend(pdf_to_images(file))
84
+ elif name.endswith((".jpg", ".jpeg", ".png")):
85
  img = Image.open(file).convert("RGBA")
86
  images.append(img)
87
  else:
88
  raise gr.Error(f"不支援的檔案格式:{name}")
89
  return process_and_combine(images, prefix)
90
 
91
+ # Gradio 舊版介面
92
+ iface = gr.Interface(
93
+ fn=process_inputs,
94
+ inputs=[
95
+ gr.inputs.File(label="📎 上傳 PDF 或圖片", type="file", multiple=True),
96
+ gr.inputs.Textbox(label="檔名前綴(可選)", default="result_"),
97
+ ],
98
+ outputs=[
99
+ gr.outputs.Gallery(label="🖼️ 合成結果"),
100
+ gr.outputs.File(label="⬇️ 下載 ZIP"),
101
+ gr.outputs.Textbox(label="📄 處理日誌")
102
+ ],
103
+ title="PDF 圖像合成工具",
104
+ description="📄🖼️ 支援上傳 PDF 或圖像,合成到固定背景圖中"
105
+ )
106
 
107
  if __name__ == "__main__":
108
+ iface.launch()