PDF 转成图片

PDF 转成图片

依赖库:pdf2image,(内部调用 poppler,所以需要安装 poppler)
https://github.com/oschwartz10612/poppler-windows/releases/

  • 但是 poppler 的 bin 目录添加环境变量,程序也无法察觉到 ===> pdf2image 不会自动搜索系统 PATH(这是它的设计缺陷)
  • 所以在程序中,手动指定 path
 pages = convert_from_path(pdf_path, dpi=dpi, poppler_path=r'D:\Release-25.11.0-0\poppler-25.11.0\Library\bin')

完整程序

import os
import threading
from tkinter import Tk, Label, Button, Entry, filedialog, StringVar, ttk, messagebox
from pdf2image import convert_from_path

def select_pdf():
    path = filedialog.askopenfilename(
        title="选择 PDF 文件",
        filetypes=[("PDF 文件", "*.pdf")]
    )
    pdf_path_var.set(path)

def select_output_dir():
    path = filedialog.askdirectory(title="选择输出目录")
    output_dir_var.set(path)

def convert_pdf():
    pdf_path = pdf_path_var.get()
    output_dir = output_dir_var.get()
    dpi = dpi_var.get()
    fmt = format_var.get().lower()

    if not pdf_path:
        messagebox.showerror("错误", "请选择 PDF 文件")
        return

    if not output_dir:
        messagebox.showerror("错误", "请选择输出目录")
        return

    try:
        dpi = int(dpi)
    except:
        messagebox.showerror("错误", "DPI 必须是整数")
        return

    # 启动异步线程执行转换(防止 GUI 卡死)
    threading.Thread(target=convert_worker, args=(pdf_path, output_dir, dpi, fmt), daemon=True).start()

def convert_worker(pdf_path, output_dir, dpi, fmt):
    progress_bar["value"] = 0
    progress_label.config(text="正在加载 PDF...")

    try:
        pages = convert_from_path(pdf_path, dpi=dpi, poppler_path=r'D:\Release-25.11.0-0\poppler-25.11.0\Library\bin')
    except Exception as e:
        print(pdf_path)
        print("=======")
        messagebox.showerror("错误", f"PDF 读取失败:\n{e}")
        return

    total = len(pages)
    progress_bar["maximum"] = total

    try:
        for i, page in enumerate(pages):
            filename = os.path.join(output_dir, f"page_{i+1}.{fmt}")
            page.save(filename, fmt.upper())

            progress_bar["value"] = i + 1
            progress_label.config(text=f"正在转换第 {i+1}/{total} 页...")
    except Exception as e:
        messagebox.showerror("错误", f"转换失败:\n{e}")
        return

    progress_label.config(text="完成!")
    messagebox.showinfo("完成", f"全部页面已成功导出至:\n{output_dir}")

# GUI -----------------------------

root = Tk()
root.title("PDF 分页保存为图片转换器")
root.geometry("500x350")

Label(root, text="选择 PDF 文件:").pack()
pdf_path_var = StringVar()
Entry(root, textvariable=pdf_path_var, width=60).pack()
Button(root, text="浏览...", command=select_pdf).pack(pady=5)

Label(root, text="选择输出目录:").pack()
output_dir_var = StringVar()
Entry(root, textvariable=output_dir_var, width=60).pack()
Button(root, text="浏览...", command=select_output_dir).pack(pady=5)

Label(root, text="DPI(清晰度,默认 200):").pack()
dpi_var = StringVar(value="200")
Entry(root, textvariable=dpi_var, width=10).pack()

Label(root, text="输出图片格式:").pack()
format_var = StringVar(value="PNG")
ttk.Combobox(root, textvariable=format_var, values=["PNG", "JPG"], width=10).pack()

# 进度条
progress_label = Label(root, text="等待开始...")
progress_label.pack(pady=10)

progress_bar = ttk.Progressbar(root, length=350)
progress_bar.pack()

Button(root, text="开始转换", command=convert_pdf, width=20).pack(pady=15)

root.mainloop()

posted @ 2025-11-25 15:45  爱新觉罗LQ  阅读(0)  评论(0)    收藏  举报