在日常工作中,我们经常需要将多个图像文件合并到一个PDF文档中,以便于查看、共享或存档。虽然现有的一些工具可以实现这一功能,但开发一个自定义的GUI工具可以更好地满足特定需求,并提供更好的用户体验。
在本文中,我将介绍如何使用Python、wxPython和PyMuPDF库创建一个简单的图形界面程序,用于将指定文件夹中的PNG图像合并为一个PDF文件。
程序概述
我们的程序包含以下主要部分:
1. **wxPython GUI** - 提供用户界面,包括文件选择器、图像预览和文件列表控件。
2. **PyMuPDF库** - 用于创建和操作PDF文件,将PNG图像插入到PDF页面中。
3. **Python文件操作** - 用于遍历文件夹和获取文件信息。
下面是程序的用户界面截图:
使用步骤:
1. 运行程序后,选择包含PNG图像的文件夹
2. 在左侧的列表框中,所有PNG文件名将被列出。单击任一文件名,右侧区域会显示该图像的预览。
3. 选中要合并到PDF中的PNG文件,点击">>"按钮将其移动到右侧列表框中。
4. 点击"生成PDF"按钮,选择PDF文件的保存路径。
5. 程序将按照右侧列表框中的顺序,将PNG图像合并到一个新的PDF文件中。
6. 合并完成后,会弹出一个对话框,显示PDF文件的保存路径。
C:\pythoncode\new\pngToPdf.py
代码解析
import os
import wx
import fitz # PyMuPDF库
class PDFMergeApp(wx.App):
def __init__(self):
super().__init__()
self.frame = PDFMergeFrame(None)
self.frame.Show()
class PDFMergeFrame(wx.Frame):
def __init__(self, parent):
super().__init__(parent, title="PDF合并工具")
panel = wx.Panel(self)
# 创建控件
self.dir_picker = wx.DirPickerCtrl(panel, message="选择PNG文件夹")
self.list_box1 = wx.ListBox(panel, style=wx.LB_SINGLE)
self.picture = wx.StaticBitmap(panel)
self.list_box2 = wx.ListBox(panel, style=wx.LB_EXTENDED)
move_btn = wx.Button(panel, label=">>")
generate_btn = wx.Button(panel, label="生成PDF")
# 绑定事件处理函数
self.dir_picker.Bind(wx.EVT_DIRPICKER_CHANGED, self.update_list_box1)
self.list_box1.Bind(wx.EVT_LISTBOX, self.display_image)
move_btn.Bind(wx.EVT_BUTTON, self.move_to_list_box2)
generate_btn.Bind(wx.EVT_BUTTON, self.generate_pdf)
# 布局
sizer = wx.BoxSizer(wx.HORIZONTAL)
left_sizer = wx.BoxSizer(wx.VERTICAL)
right_sizer = wx.BoxSizer(wx.VERTICAL)
left_sizer.Add(self.dir_picker, 0, wx.EXPAND | wx.ALL, 5)
left_sizer.Add(self.list_box1, 1, wx.EXPAND | wx.ALL, 5)
right_sizer.Add(self.picture, 1, wx.EXPAND | wx.ALL, 5)
right_sizer.Add(self.list_box2, 1, wx.EXPAND | wx.ALL, 5)
right_sizer.Add(generate_btn, 0, wx.ALIGN_CENTER | wx.ALL, 5)
sizer.Add(left_sizer, 1, wx.EXPAND | wx.ALL, 5)
sizer.Add(move_btn, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
sizer.Add(right_sizer, 1, wx.EXPAND | wx.ALL, 5)
panel.SetSizer(sizer)
def update_list_box1(self, event):
self.list_box1.Clear()
dir_path = self.dir_picker.GetPath()
for filename in os.listdir(dir_path):
if filename.endswith(".png"):
self.list_box1.Append(filename)
def display_image(self, event):
selection = event.GetSelection()
filename = self.list_box1.GetString(selection)
dir_path = self.dir_picker.GetPath()
image = wx.Image(os.path.join(dir_path, filename), wx.BITMAP_TYPE_PNG)
self.picture.SetBitmap(wx.Bitmap(image))
def move_to_list_box2(self, event):
selections = self.list_box1.GetSelections()
items = [self.list_box1.GetString(sel) for sel in selections]
for item in items:
self.list_box2.Append(item)
self.list_box1.Delete(self.list_box1.FindString(item))
def generate_pdf(self, event):
dir_path = self.dir_picker.GetPath()
pdf_path = wx.FileSelector("保存PDF文件", wildcard="PDF 文件 (*.pdf)|*.pdf",
flags=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if pdf_path:
pdf = fitz.open()
for index in range(self.list_box2.GetCount()):
filename = self.list_box2.GetString(index)
image_path = os.path.join(dir_path, filename)
img = fitz.Pixmap(image_path)
page = pdf.new_page(width=img.width, height=img.height)
page.insert_image(rect=page.rect, pixmap=img)
pdf.save(pdf_path)
pdf.close()
wx.MessageBox(f"已成功生成PDF文件: {pdf_path}", "完成", wx.OK | wx.ICON_INFORMATION)
if __name__ == "__main__":
app = PDFMergeApp()
app.MainLoop()
这段代码的核心在于wxPython GUI的构建和PyMuPDF库的使用。
在创建GUI时,我们定义了各种控件,如文件夹选择器、列表框和图像预览区域,并将它们合理布局。通过事件绑定,实现了不同控件的交互功能,例如选择文件夹后更新文件列表、预览图像、在列表框之间移动文件等。
合并PNG到PDF的关键是使用PyMuPDF库。我们遍历右侧列表框中的PNG文件路径,使用`fitz.Pixmap`打开每个PNG图像。然后,为每个图像创建一个新的PDF页面,并使用`page.insert_image`方法将图像插入到该页面中。最后,将所有页面保存到一个新的PDF文件中。
总结
通过结合wxPython和PyMuPDF,我们创建了一个方便实用的工具,可以快速将PNG图像合并为PDF文档。该程序不仅操作简单,还具有预览功能,可以确认要合并的图像顺序。你可以根据自己的需求对代码进行进一步扩展和定制,例如支持其他图像格式、调整图像大小或添加水印等。无论是用于工作还是个人使用,这个小工具都将为你节省宝贵的时间和精力。