吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 922|回复: 5
收起左侧

[Windows] Python编写的小工具-PDF拼接高清图片

[复制链接]
xhlbudd 发表于 2026-5-17 19:43
本人从事制药行业法规事务工作,业余时间运营着一个公众号,经常需要把国家药品监督管理局发布的PDF版法规转成图片通过公众号进行分享。直接使用Windows的截图工具,或者Adobe Acrobat Pro(专业版)虽然都可以成功转换,但是清晰度都不尽如人意,也无法自行指定导出的清晰度,也无法实现自行定义的拼接效果。今天用Python编写了一个小工具,可以指定清晰度(300dpi即可导出高清图片),图片接拼方式(如3行2列),欢迎大家下载试用:

通过百度网盘分享的文件:202605 PDF拼接高清图片
链接: https://pan.baidu.com/s/1SQxZJVahqP3sOaiGt0i-9A 提取码: 52pj

同时把源代码分享如下,请吾爱的大神们多多指点:
[Python] 纯文本查看 复制代码
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import fitz
from PIL import Image
import os
import threading
import math


def convert_pdf_thread():
    threading.Thread(target=convert_pdf, daemon=True).start()


def convert_pdf():
    pdf_path = pdf_entry.get()
    if not pdf_path:
        messagebox.showwarning("提示", "请选择 PDF 文件")
        return

    try:
        rows = int(row_var.get())
        cols = int(col_var.get())
        dpi = int(dpi_var.get())
    except ValueError:
        messagebox.showerror("错误", "请输入有效数字")
        return

    if rows <= 0 or cols <= 0:
        messagebox.showerror("错误", "行数和列数必须大于 0")
        return

    output_dir = filedialog.askdirectory(title="选择图片保存目录")
    if not output_dir:
        return

    doc = fitz.open(pdf_path)
    total_pages = len(doc)

    # 进度窗口
    progress_win = tk.Toplevel(root)
    progress_win.title("正在处理")
    progress_win.geometry("360x120")
    progress_win.resizable(False, False)

    tk.Label(progress_win, text="正在转换 PDF 页面...").pack(pady=10)

    progress_bar = ttk.Progressbar(
        progress_win, length=300, mode="determinate", maximum=total_pages
    )
    progress_bar.pack(pady=5)

    progress_label = tk.Label(progress_win, text="0 / {}".format(total_pages))
    progress_label.pack()

    zoom = dpi / 72
    mat = fitz.Matrix(zoom, zoom)

    images = []
    for i in range(total_pages):
        page = doc.load_page(i)
        pix = page.get_pixmap(matrix=mat)
        img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
        images.append(img)

        progress_bar["value"] = i + 1
        progress_label.config(text=f"{i + 1} / {total_pages}")
        progress_win.update_idletasks()

    doc.close()

    # 网格拼接
    pages_per_image = rows * cols
    output_images = []

    for i in range(0, len(images), pages_per_image):
        chunk = images[i:i + pages_per_image]

        while len(chunk) < pages_per_image:
            chunk.append(Image.new("RGB", chunk[0].size, (255, 255, 255)))

        widths, heights = zip(*(img.size for img in chunk))

        cell_width = max(widths)
        cell_height = max(heights)

        big_width = cell_width * cols
        big_height = cell_height * rows

        new_img = Image.new("RGB", (big_width, big_height), (255, 255, 255))

        for idx, img in enumerate(chunk):
            r = idx // cols
            c = idx % cols
            new_img.paste(img, (c * cell_width, r * cell_height))

        output_images.append(new_img)

    # 保存
    base_name = os.path.splitext(os.path.basename(pdf_path))[0]
    for idx, img in enumerate(output_images, start=1):
        out_path = os.path.join(output_dir, f"{base_name}_{idx}.png")
        img.save(out_path, "PNG")

    progress_win.destroy()
    messagebox.showinfo("完成", f"成功导出 {len(output_images)} 张图片")


# ===== GUI =====
root = tk.Tk()
root.title("PDF 转拼接图片工具 by xhlbudd@52pojie")
root.geometry("440x320")

# PDF
tk.Label(root, text="PDF 文件:").pack(anchor="w", padx=10, pady=(10, 0))
pdf_entry = tk.Entry(root, width=52)
pdf_entry.pack(padx=10)

tk.Button(
    root,
    text="浏览",
    command=lambda: pdf_entry.insert(
        0, filedialog.askopenfilename(filetypes=[("PDF Files", "*.pdf")])
    ),
).pack(pady=5)

# 拼接布局
frame_layout = tk.Frame(root)
frame_layout.pack(pady=10)

tk.Label(frame_layout, text="拼接布局(行 × 列):").grid(row=0, column=0, padx=5)

row_var = tk.StringVar(value="3")
col_var = tk.StringVar(value="1")

tk.Entry(frame_layout, textvariable=row_var, width=5).grid(row=0, column=1)
tk.Label(frame_layout, text="×").grid(row=0, column=2)
tk.Entry(frame_layout, textvariable=col_var, width=5).grid(row=0, column=3)

# DPI
tk.Label(root, text="导出清晰度(DPI):").pack(anchor="w", padx=10)
dpi_var = tk.StringVar(value="300")
tk.Entry(root, textvariable=dpi_var, width=10).pack(anchor="w", padx=10)

# 开始按钮
tk.Button(
    root,
    text="开始转换",
    bg="#4CAF50",
    fg="white",
    height=2,
    command=convert_pdf_thread,
).pack(pady=15)

root.mainloop()

软件截图

软件截图

导出图片效果-3x2

导出图片效果-3x2

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

limingzhi2050 发表于 2026-5-18 18:28
感谢分享 这个不错
yimin 发表于 2026-5-18 23:58
 楼主| xhlbudd 发表于 2026-5-19 00:00
yimin 发表于 2026-5-18 23:58
好厉害呀

谢谢支持,希望对大家有帮助,也欢迎大家提出宝贵意见~~
gaoxiaoao 发表于 2026-5-19 09:29
虽然多种方法可以实现,这个一步到位还是香,同制药行业。楼主什么公众号
 楼主| xhlbudd 发表于 2026-5-20 18:23
gaoxiaoao 发表于 2026-5-19 09:29
虽然多种方法可以实现,这个一步到位还是香,同制药行业。楼主什么公众号

谢谢支持,希望小工具对大家整理和分享国家药品监督管理局的法规有所帮助~~
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-7-5 17:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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