递归火山软件开发平台

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 火山 源码 类库
查看: 78|回复: 3
打印 上一主题 下一主题

[视窗] 求助图片转PDF

[复制链接]

2

主题

15

帖子

112

积分

注册会员

Rank: 2

积分
112
跳转到指定楼层
楼主
发表于 昨天 13:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
有没有火山视窗把两张图片合成一个PDF文件的例子?求分享一个。
回复

使用道具 举报

461

主题

1万

帖子

4万

积分

超级版主

Rank: 8Rank: 8

积分
45932
沙发
发表于 昨天 16:45 | 只看该作者
火山提供了pdf操作库。可以看自带案例,找找添加图片的方法。然后把图片添加进去就行了。
安卓无障碍实战课:点击查看
交流群:641526939
回复

使用道具 举报

60

主题

271

帖子

1324

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
1324
板凳
发表于 昨天 22:57 | 只看该作者
刚好前几天我也有这样的需求,用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()
复制代码
回复

使用道具 举报

94

主题

564

帖子

2253

积分

金牌会员

Rank: 6Rank: 6

积分
2253
地板
发表于 14 分钟前 | 只看该作者
用PY那带的东西就太多太大了
火山PC HP_SOCKET 控件 交流群:956446702
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-10-18 00:35 , Processed in 0.086875 second(s), 17 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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