STLooo commited on
Commit
e3ae23b
·
verified ·
1 Parent(s): 19d5abf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -44
app.py CHANGED
@@ -3,7 +3,7 @@ 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,41 +11,34 @@ TARGET_WIDTH, TARGET_HEIGHT = 2133, 1200
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 轉圖片(PyMuPDF)
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:
35
- alpha = fg[:, :, 3] / 255.0
36
- for c in range(3):
37
- bg[y:y+TARGET_HEIGHT, x:x+TARGET_WIDTH, c] = (
38
- alpha * fg[:, :, c] + (1 - alpha) * bg[y:y+TARGET_HEIGHT, x:x+TARGET_WIDTH, c]
39
- )
40
- else:
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"):
@@ -56,9 +49,8 @@ def process_and_combine(images, prefix):
56
  combined = overlay_image(bg.copy(), img, *POS1)
57
  combined = overlay_image(combined, img, *POS2)
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
 
@@ -69,10 +61,9 @@ def process_and_combine(images, prefix):
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)} 張圖片,已打包 ZIP"
74
-
75
- # 處理輸入
76
  def process_inputs(files, prefix):
77
  prefix = prefix.strip() or "result_"
78
  images = []
@@ -81,27 +72,32 @@ def process_inputs(files, prefix):
81
  if name.endswith(".pdf"):
82
  images.extend(pdf_to_images(file))
83
  elif name.endswith((".png", ".jpg", ".jpeg")):
84
- img = Image.open(file).convert("RGBA")
 
 
85
  images.append(img)
86
  else:
87
  raise gr.Error(f"不支援的檔案格式:{name}")
88
  return process_and_combine(images, prefix)
89
 
90
- # Gradio Blocks UI
91
- with gr.Blocks(title="PDF與圖片合成工具") as demo:
92
- gr.Markdown("### 📄🖼️ PDF / 圖片 雙輸入合成工具(背景為 7872x1200)")
93
-
94
- with gr.Row():
95
- files = gr.Files(label="📎 上傳 PDF 或圖片", file_types=[".pdf", ".jpg", ".jpeg", ".png"])
96
- prefix = gr.Textbox(label="輸出檔名前綴", placeholder="例如:poster_", value="result_")
97
- run_btn = gr.Button("🚀 開始合成", variant="primary")
98
-
99
- with gr.Row():
100
- gallery = gr.Gallery(label="🖼️ 預覽", columns=3, height="auto")
101
- zip_file = gr.File(label="下載 ZIP")
102
- log = gr.Textbox(label="📄 日誌", interactive=False)
103
-
104
- run_btn.click(fn=process_inputs, inputs=[files, prefix], outputs=[gallery, zip_file, log])
 
 
 
105
 
106
  if __name__ == "__main__":
107
  demo.launch()
 
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(pdf_file):
23
  images = []
24
+ with fitz.open(pdf_file.name) as doc:
25
+ for page in doc:
26
+ pix = page.get_pixmap(matrix=fitz.Matrix(2, 2), colorspace=fitz.csRGB)
27
+ img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
28
+ images.append(img)
29
  return images
30
 
31
+ # 合成圖像
32
  def overlay_image(bg, fg_img, x, y):
33
+ fg = fg_img.resize((TARGET_WIDTH, TARGET_HEIGHT), resample=Image.BILINEAR)
34
+ fg = np.array(fg)
35
+ bg[y:y+TARGET_HEIGHT, x:x+TARGET_WIDTH] = fg[:, :, :3]
 
 
 
 
 
 
36
  return bg
37
 
38
+ # 合成 + 壓縮
39
  def process_and_combine(images, prefix):
40
+ bg_pil = Image.open(BG_PATH).convert("RGB")
41
+ bg = np.array(bg_pil)
 
42
 
43
  for f in os.listdir(OUTPUT_DIR):
44
  if f.endswith(".jpg"):
 
49
  combined = overlay_image(bg.copy(), img, *POS1)
50
  combined = overlay_image(combined, img, *POS2)
51
  output_path = os.path.join(OUTPUT_DIR, f"{prefix}{i:03d}.jpg")
52
+ cv2.imwrite(output_path, cv2.cvtColor(combined, cv2.COLOR_RGB2BGR))
53
  results.append((output_path, f"{prefix}{i:03d}"))
 
54
  if i % 10 == 0:
55
  gc.collect()
56
 
 
61
  for f in sorted(os.listdir(OUTPUT_DIR)):
62
  if f.endswith(".jpg"):
63
  zipf.write(os.path.join(OUTPUT_DIR, f), arcname=f)
64
+ return results, ZIP_PATH, f"✅ 共合成 {len(results)} 張圖,已打包 ZIP"
65
 
66
+ # 主流程
 
 
67
  def process_inputs(files, prefix):
68
  prefix = prefix.strip() or "result_"
69
  images = []
 
72
  if name.endswith(".pdf"):
73
  images.extend(pdf_to_images(file))
74
  elif name.endswith((".png", ".jpg", ".jpeg")):
75
+ img = Image.open(file)
76
+ if img.mode != "RGB":
77
+ img = img.convert("RGB")
78
  images.append(img)
79
  else:
80
  raise gr.Error(f"不支援的檔案格式:{name}")
81
  return process_and_combine(images, prefix)
82
 
83
+ # Gradio UI with Interface
84
+ def ui_interface(files, prefix):
85
+ return process_inputs(files, prefix)
86
+
87
+ demo = gr.Interface(
88
+ fn=ui_interface,
89
+ inputs=[
90
+ gr.File(label="📎 上傳 PDF 或圖片", file_types=[".pdf", ".png", ".jpg", ".jpeg"], multiple=True),
91
+ gr.Textbox(label="檔名前綴(可選)", placeholder="例如:poster_")
92
+ ],
93
+ outputs=[
94
+ gr.Gallery(label="🖼預覽", columns=3, height="auto"),
95
+ gr.File(label="⬇️ 下載 ZIP"),
96
+ gr.Textbox(label="📄 日誌")
97
+ ],
98
+ title="PDF 圖片合成���具",
99
+ description="📄🖼️ 將 PDF 或圖片套用背景合成為長圖,背景為固定寬度 7872x1200。"
100
+ )
101
 
102
  if __name__ == "__main__":
103
  demo.launch()