递归火山软件开发平台

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 火山 源码 类库

多图片合成PDF(已解决)

查看数: 369 | 评论数: 4 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2025-10-17 13:00

正文摘要:

本帖最后由 hhhyxb 于 2025-10-31 16:08 编辑 有没有火山视窗把两张图片合成一个PDF文件的例子?求分享一个。 下面是我的解决代码截图,供参考。 ...

回复

hhhyxb 发表于 前天 17:43
a759077146 发表于 2025-10-17 22:57
刚好前几天我也有这样的需求,用py支持库调用py解决。

我搞定了。用的自带的pdf库
cdmmye 发表于 2025-10-18 00:20:34
用PY那带的东西就太多太大了
a759077146 发表于 2025-10-17 22:57:53
刚好前几天我也有这样的需求,用py支持库调用py解决。

  1. import os
  2. import re
  3. import sys
  4. import traceback
  5. from datetime import datetime

  6. import tkinter as tk
  7. from tkinter import filedialog, messagebox

  8. from PIL import Image, ImageOps

  9. IMAGE_EXTS = {".jpg", ".jpeg", ".png", ".bmp", ".webp", ".tif", ".tiff"}
  10. # --------------------------


  11. def is_image_file(path: str) -> bool:
  12.     ext = os.path.splitext(path)[1].lower()
  13.     return ext in IMAGE_EXTS


  14. def natural_key(s: str):

  15.     return [int(t) if t.isdigit() else t for t in re.split(r'(\d+)', s.lower())]


  16. def load_image_as_rgb(path: str) -> Image.Image:

  17.     im = Image.open(path)
  18.     try:
  19.         im = ImageOps.exif_transpose(im)  # 遵循相机 EXIF 方向
  20.         if im.mode in ("RGBA", "LA"):
  21.             # 透明通道:铺白底
  22.             bg = Image.new("RGB", im.size, (255, 255, 255))
  23.             bg.paste(im, mask=im.split()[-1])
  24.             im = bg
  25.         elif im.mode != "RGB":
  26.             im = im.convert("RGB")
  27.         # 拷贝以便尽快关闭原文件句柄
  28.         out = im.copy()
  29.     finally:
  30.         im.close()
  31.     return out


  32. def merge_images_to_pdf(img_paths, output_pdf: str):
  33.     if not img_paths:
  34.         raise RuntimeError("未找到可用图片。")

  35.     images = []
  36.     first_image = None
  37.     for i, p in enumerate(img_paths):
  38.         rgb_img = load_image_as_rgb(p)
  39.         if i == 0:
  40.             first_image = rgb_img
  41.         else:
  42.             images.append(rgb_img)

  43.     # 导出 PDF
  44.     first_image.save(
  45.         output_pdf,
  46.         "PDF",
  47.         resolution=100.0,
  48.         save_all=True,
  49.         append_images=images,
  50.     )

  51.     # 显式关闭(释放内存)
  52.     first_image.close()
  53.     for im in images:
  54.         im.close()


  55. def choose_dir_and_run():
  56.     root = tk.Tk()
  57.     root.withdraw()  # 隐藏主窗口,只弹出选择框

  58.     folder = filedialog.askdirectory(title="选择包含图片的文件夹")
  59.     if not folder:
  60.         # 用户取消
  61.         return

  62.     try:
  63.         # 收集图片
  64.         all_files = [os.path.join(folder, f) for f in os.listdir(folder)]
  65.         img_files = [p for p in all_files if os.path.isfile(p) and is_image_file(p)]
  66.         img_files.sort(key=lambda p: natural_key(os.path.basename(p)))

  67.         if not img_files:
  68.             messagebox.showwarning("提示", "该文件夹下未找到可用的图片文件。")
  69.             return

  70.         # 输出路径
  71.         ts = datetime.now().strftime("%Y%m%d_%H%M%S")
  72.         out_pdf = os.path.join(folder, f"合并输出_{ts}.pdf")

  73.         # 合并
  74.         merge_images_to_pdf(img_files, out_pdf)

  75.         messagebox.showinfo("完成", f"合并完成!\n共 {len(img_files)} 张图片\n已保存:\n{out_pdf}")

  76.     except Exception as e:
  77.         traceback.print_exc()
  78.         messagebox.showerror("错误", f"合并失败:{e}")


  79. if __name__ == "__main__":
  80.     choose_dir_and_run()
复制代码
创世魂 发表于 2025-10-17 16:45:20
火山提供了pdf操作库。可以看自带案例,找找添加图片的方法。然后把图片添加进去就行了。

QQ|Archiver|手机版|小黑屋|递归火山软件开发平台 ( 鄂ICP备18029190号 )

GMT+8, 2025-11-1 13:16 , Processed in 0.091523 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表