当前位置:首页 > 技术 > 正文内容

基于PyMuPDF与ReportLab的PDF图片双向转换工具

访客 技术 2026年10月9日 4

概述

在日常工作中,我们经常需要在PDF与图片格式间进行转换,例如将PDF每页导出为图片进行编辑,或将一组图片合并成一个PDF文档。本文介绍一个用Python实现的双向转换工具,它不仅提供了命令行脚本,还封装了基于Tkinter的图形界面,支持批量处理与画质选择。

依赖库

主要依赖:

  • PyMuPDF (fitz):用于解析PDF并渲染页面为图像。
  • Pillow (PIL):辅助处理图片尺寸。
  • ReportLab:将图片按序写入PDF。
  • Tkinter:构建桌面交互界面。

安装命令:

pip install pymupdf pillow reportlab

核心转换逻辑

以下代码展示PDF转图片的功能,通过缩放矩阵控制输出分辨率:

import fitz
import os

def export_pages_to_image(file_path, scale=2.0):
    doc = fitz.open(file_path)
    base = os.path.splitext(os.path.basename(file_path))[0]
    out_dir = os.path.join(os.path.dirname(file_path), f"{base}_images")
    os.makedirs(out_dir, exist_ok=True)

    for idx in range(len(doc)):
        page = doc[idx]
        matrix = fitz.Matrix(scale, scale)
        pixmap = page.get_pixmap(matrix=matrix)
        dest = os.path.join(out_dir, f"page_{idx+1:04d}.png")
        pixmap.save(dest)
        print(f"Exported page {idx+1} -> {dest}")
    doc.close()
    return out_dir

图片合并回PDF时,使用ReportLab按比例将图片填充至页面:

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from PIL import Image
import os

def compile_images_to_pdf(image_dir, output_path):
    valid_files = sorted(
        [f for f in os.listdir(image_dir) if f.lower().endswith(('.png', '.jpg', '.jpeg'))]
    )
    if not valid_files:
        raise FileNotFoundError("目录中没有可用的图片文件")

    c = canvas.Canvas(output_path, pagesize=A4)
    page_w, page_h = A4
    for img_file in valid_files:
        img_path = os.path.join(image_dir, img_file)
        with Image.open(img_path) as im:
            im_w, im_h = im.size
            factor = min(page_w / im_w, page_h / im_h)
            scaled_w = im_w * factor
            scaled_h = im_h * factor
            # 居中对齐
            x = (page_w - scaled_w) / 2
            y = (page_h - scaled_h) / 2
            c.drawImage(img_path, x, y, width=scaled_w, height=scaled_h)
            c.showPage()
    c.save()
    print(f"PDF已生成:{output_path}")

图形界面实现

使用Tkinter的Notebook组件制作双标签页,分别对应"PDF转图片"和"图片转PDF"。用户可浏览文件/目录、选择画质(标清/高清/超清),并通过进度条与日志区域获得实时反馈。

import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import threading

class ConverterApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("PDF与图片互转工具")
        self.geometry("600x450")
        self._init_ui()

    def _init_ui(self):
        self.notebook = ttk.Notebook(self)
        self.tab1 = ttk.Frame(self.notebook)
        self.tab2 = ttk.Frame(self.notebook)
        self.notebook.add(self.tab1, text="PDF → 图片")
        self.notebook.add(self.tab2, text="图片 → PDF")
        self.notebook.pack(expand=True, fill="both")
        self._build_pdf_to_image_tab()
        self._build_image_to_pdf_tab()

    def _build_pdf_to_image_tab(self):
        # 文件选择、输出目录、画质下拉框、进度条、日志
        # 绑定转换函数,运行在独立线程中避免阻塞UI
        pass

    def _build_image_to_pdf_tab(self):
        # 类似结构
        pass

    def _start_conversion(self, target, **kwargs):
        thread = threading.Thread(target=target, kwargs=kwargs)
        thread.daemon = True
        thread.start()

if __name__ == "__main__":
    ConverterApp().mainloop()

(完整界面逻辑省略,实际代码包含文件浏览、参数收集与进度回调等功能。)

转换工具界面
工具运行界面

使用说明

  1. 选择PDF文件并指定图片输出目录,设置所需画质后点击"转换"。
  2. 图片转PDF时,选择存放图片的文件夹,自动生成以时间戳命名的输出PDF。
  3. 所有操作均有进度提示,转换完成后弹出通知。

封装与分发

可以使用PyInstaller将整个应用打包为独立的exe文件,方便无Python环境的用户使用:

pyinstaller --onefile --windowed converter.py

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。