在孩子的学习过程中,我们常常会遇到这样的困扰:学校老师发的作业是以 A3 格式的 PDF 文件呈现的,然而家里的打印机却只支持 A4 打印。这时候,要是能有一个简单的方法把 A3 的 PDF 转换为 A4 可打印的格式就好了。别担心,今天我就来分享一下我是如何用 Python 编写一个实用的转换程序,轻松解决这个问题的。
我通过编写 Python 程序,借助几个常见的 Python 库,实现了将 A3 格式的 PDF 文件进行分割和重新组合,最终生成适合 A4 打印机打印的 PDF 文件。整个过程只需要简单的几个步骤,就可以让原本无法直接打印的作业变得可以轻松打印出来。
这个程序主要完成了以下几个关键的任务:
- PDF 转图片:把 A3 格式的 PDF 文件逐页转换为图片,并将这些图片保存到一个专门的文件夹中。这样做的好处是方便后续对页面内容进行处理。
- 图片分割:将生成的图片从中间左右分割成两张,模拟将 A3 页面拆分成两个 A4 页面的效果。分割后的图片会被保存到另一个新的文件夹中。
- 图片合并成 PDF:按照文件名的顺序,将分割后的图片重新合并成一个新的 PDF 文件。这个新的 PDF 文件就是适合 A4 打印机打印的格式了。
下面是具体的代码实现:
#!/usr/bin/python3
# -*- coding: utf-8 -*-import fitz
import time
import os
import sys
import cv2
import numpy as np
from fpdf import FPDF
from PIL import Image# pip install PyMuPDF
# pip install opencv-python
# pip install fpdf
# pip install Pillow
# 将pdf分割为图片,并建立一个images1文件夹保存之 传入要拆解的pdf文件名
def to_image(file_name):dir1 = get_filename_without_ext(file_name) + "_images1"if not os.path.exists(dir1):os.mkdir(dir1)time_start = time.time()doc = fitz.open(file_name)rotate = int(0)zoom_x = 2.0zoom_y = 2.0trans = fitz.Matrix(zoom_x, zoom_y)print("%s开始转换..." % file_name)pg = 0for page in doc:timep_start = time.time()pg += 1pm = page.get_pixmap(matrix=trans, alpha=False)new_full_name = dir1 + "/" + file_name.split(".")[0]filename1 = "{0:s}{1:0>3d}.jpg".format(new_full_name, pg)pm.save(filename1)timep_end = time.time()print('第 ' + str(pg) + ' 页生成图片累计用时:' + str(timep_end - timep_start))time_end = time.time()print('拆解累计用时:' + str(time_end - time_start))# 将images1文件夹中的每个图片,左右分割为两张,并新建images2文件夹以保存文件
def cut_img(file_name):dir1 = get_filename_without_ext(file_name) + "_images1"for img in os.listdir(dir1):#print(img)#image = cv2.imread(dir1 + "/" + img)#解决路径中含有中文的问题image = cv2.imdecode(np.fromfile(dir1 + "/" + img, dtype=np.uint8), cv2.IMREAD_COLOR)if image is None:print("failed to load image")else:x0 = int(image.shape[1]/2)print('x:' + str(x0))dir2 = get_filename_without_ext(file_name) + "_images2"if not os.path.exists(dir2):os.mkdir(dir2)img1 = image[:, 0:x0-100]img2 = image[:, x0-100:]#cv2.imwrite(dir2 + "/" + img[:-4] + '1.jpg', img1)#cv2.imwrite(dir2 + "/" + img[:-4] + '2.jpg', img2)#解决路径中含有中文的问题cv2.imencode('.jpg', img1)[1].tofile(dir2 + "/" + img[:-4] + '1.jpg')cv2.imencode('.jpg', img2)[1].tofile(dir2 + "/" + img[:-4] + '2.jpg')# 将images2文件夹中的图片合并成为一个pdf,按照文件名的顺序 传入输出的pdf文件名
def makePdf(file_name, pdfFileName):dir2 = get_filename_without_ext(file_name) + "_images2"print(dir2)listPages = [dir2 + "/" + imgFileName for imgFileName in os.listdir(dir2)]#print(listPages)cover = Image.open(listPages[0])if cover is None:print('cover is none')else:width, height = cover.sizepdf = FPDF(unit="pt", format = [width, height])for page in listPages:pdf.add_page()pdf.image(page, 0, 0)pdf.output(pdfFileName, "F")# 获取文件名不带后缀
def get_filename_without_ext(filepath):filename_with_extension = os.path.basename(filepath)filename, file_extension = os.path.splitext(filename_with_extension)return filenamedef check(question):option = input(">> " + question + " Yes(Y) // No(N): \n>> ")return option == "Y" or option == "yes" or option == "Yes" or option == "y"def fileObj(filePath):print(">> 载入成功, 当前文件对象路径:" + filePath + "\n")while True:print("### 当前文件对象路径:" + filePath + " ###\n")option = input("请选择要执行的操作: 分割(S), 合并(M), 退出当前对象(Q)\n>>")option = option.upper()if option == "S" and check("是否分割"):to_image(filePath)cut_img(filePath)if option == "M" and check("是否合并"):makePdf(filePath, get_filename_without_ext(filePath) + "_result.pdf")if option == "Q":print(">> 处理完毕\n")breakdef main():print("欢迎使用pdf切割程序\n")while True:option = input("请输入PDF文件路径:\n>>")if option == 'exit' or option == 'quit' or option == 'q':print(">> 退出!\n")breakelif option == '':print(">> 输入为空\n")elif option == 'help' or option == '-h':print(">> 请输入PDF文件路径:\n")else:if not os.path.exists(option):print(">> 路径出错!,请重新输入PDF路径:\n")continuefileObj(option)# 执行
if __name__ == "__main__":if len(sys.argv) < 2:main()else:uipath = sys.argv[1]to_image(uipath)cut_img(uipath)makePdf(uipath, get_filename_without_ext(uipath) + "_result.pdf")
通过运行这个程序,你只需要输入 A3 格式 PDF 文件的路径,程序就会自动完成分割和合并的操作,最终生成一个适合 A4 打印机打印的 PDF 文件。是不是很方便呢?