PyPDF2 | 利用 Python 实现 PDF 分割
1. PDF 分割
由于疫情影响被迫在家上网课,因此教材也只能用电子版。但有一门教材是对开的扫描版,导致在 iPad 上阅读很不友好,因此决定寻找一个工具将 PDF 对半分开。
图1 分割前的 PDF
在百度了一番后,发现大多都是使用 Adobe Acrobat 软件进行剪裁,这完全不 Pythonic,因此又找了用 Python 处理 PDF 文件的方法,最后发现了 PyPDF2 这个库,本文将利用这个库,实现对 PDF 的分割。
首先,你需要通过 pip 安装这个库:
pip install PyPDF2
实现切割 PDF 的思想很简单,只要我们能测量出 PDF 的长宽,接着分别将左右裁剪拼接即可,而 PyPDF2 已经提供了这些功能:
# PdfFileReader 模块用于读取 pdf
# PdfFileWriter 模块用于创建要保存的 pdf
from PyPDF2 import PdfFileReader, PdfFileWriter# 1. 读取 pdf
pdf_input = PdfFileReader(open('xxx.pdf', 'rb'))# 2. 创建要保存的 pdf 对象
pdf_output = PdfFileWriter()# 3. 选取第一页 pdf 读取长宽
page = pdf_input_left.getPage(0)
width = float(page.mediaBox.getWidth())
height = float(page.mediaBox.getHeight())# 4. 计算 pdf 的总页数
page_count = pdf_input_left.getNumPages()# 5. 修改某一页 pdf 的尺寸
page = pdf_input.getPage(i)
page.mediaBox.lowerLeft = (x,y)
page.mediaBox.lowerRight = (x,y)
page.mediaBox.upperLeft = (x,y)
page.mediaBox.upperRight = (x,y)# 6. 将修改好的 pdf 添加到我们要输出的文件中
pdf_output.addPage(page)# 7. 循环所有的页数后,将文件输出为 pdf 文件
pdf_output.write(open('xxx,pdf', 'wb'))
需要注意的是,PyPDF2 默认将较短的边作为 X 轴,较长的边作为 Y 轴,对应的坐标如下:
图2 纵向比例下的 PyPDF2 坐标
然而我们的 PDF 是横向比例的,如下图所示:
图3 横向比例 PDF 示例
相当于:
图4 横向比例下的 PyPDF2 坐标
即:
图5 旋转后的横向比例下的 PyPDF2 坐标
要注意与图 1 坐标的区别。
在弄清楚了 PyPDF 的坐标后,我们就可以通过调整四个角的坐标来分别获得左右两个 PDF 了,对于左边的 PDF,其对应的坐标为:
图6 左半图的 PyPDF2 坐标
因此坐标设置如下:
page_left.mediaBox.lowerLeft = (0, height/2)
page_left.mediaBox.lowerRight = (width, height/2)
page_left.mediaBox.upperLeft = (0, height)
page_left.mediaBox.upperRight = (width, height)
而右半图的坐标为:
图7 右半图的 PyPDF2 坐标
对应的坐标设置为:
page_right.mediaBox.lowerLeft = (0, 0)
page_right.mediaBox.lowerRight = (width, 0)
page_right.mediaBox.upperLeft = (0, height/2)
page_right.mediaBox.upperRight = (width, height/2)
最后汇总得:
from PyPDF2 import PdfFileReader, PdfFileWriterinfile = '应用多元统计分析 高惠璇.pdf'
outfile = '应用多元统计分析 高惠璇 split.pdf'pdf_input_left = PdfFileReader(open(infile, 'rb'))
pdf_input_right = PdfFileReader(open(infile, 'rb'))
pdf_output = PdfFileWriter()page = pdf_input_left.getPage(0)
width = float(page.mediaBox.getWidth())
height = float(page.mediaBox.getHeight())
page_count = pdf_input_left.getNumPages()for i in range(page_count):# left pagepage_left = pdf_input_left.getPage(i)page_left.mediaBox.lowerLeft = (0, height/2)page_left.mediaBox.lowerRight = (width, height/2)page_left.mediaBox.upperLeft = (0, height)page_left.mediaBox.upperRight = (width, height)pdf_output.addPage(page_left)# right pagepage_right = pdf_input_right.getPage(i)page_right.mediaBox.lowerLeft = (0, 0)page_right.mediaBox.lowerRight = (width, 0)page_right.mediaBox.upperLeft = (0, height/2)page_right.mediaBox.upperRight = (width, height/2)pdf_output.addPage(page_right)pdf_output.write(open(outfile, 'wb'))
看下转换效果,Bingo!
图8 转换后的 PDF 效果
2. 调整边缘
转换后发现,PDF 存在这黑边,因此我们可以通过调整对应的坐标来减少黑边的现象:
图9 PDF 黑边
from PyPDF2 import PdfFileReader, PdfFileWriter
def pdf_split(infile, outfile, left_margin=0, right_margin=0, down_margin=0):pdf_input_left = PdfFileReader(open(infile, 'rb')) # 读取切割为左边的 pdfpdf_input_right = PdfFileReader(open(infile, 'rb')) # 读取切割为右边的 pdfpdf_output = PdfFileWriter() # 定义要保存的 pdfpage = pdf_input_left.getPage(0) # 选取第一页 来读取 pdf 的长宽width = float(page.mediaBox.getWidth())height = float(page.mediaBox.getHeight())page_count = pdf_input_left.getNumPages() # 读取 pdf 页数for i in range(page_count):# 切割左边 pdfpage_left = pdf_input_left.getPage(i)page_left.mediaBox.lowerLeft = (0, height/2)page_left.mediaBox.lowerRight = (width, height/2)page_left.mediaBox.upperLeft = (down_margin, height-left_margin)page_left.mediaBox.upperRight = (width, height-left_margin)pdf_output.addPage(page_left)# 切割右边 pdfpage_right = pdf_input_right.getPage(i)page_right.mediaBox.lowerLeft = (down_margin, right_margin)page_right.mediaBox.lowerRight = (width, right_margin)page_right.mediaBox.upperLeft = (down_margin, height/2)page_right.mediaBox.upperRight = (width, height/2)pdf_output.addPage(page_right)pdf_output.write(open(outfile, 'wb')) # 保存 pdfprint('Done!')
infile = '应用多元统计分析 高惠璇.pdf'
outfile = '应用多元统计分析 高惠璇 split.pdf'
left_margin=10
right_margin=10
down_margin = 20
pdf_split(infile, outfile, left_margin, right_margin, down_margin)
Done!
看下最后效果:
图10 调整后的 PDF 黑边情况
其他文章推荐
机器学习算法与 Python 实现专栏
SQL 入门教程专栏
PyPDF2 | 利用 Python 实现 PDF 分割相关推荐
- 利用Python提取PDF文件中的文本信息
如何利用Python提取PDF文件中的文本信息 日常工作中我们经常会用到pdf格式的文件,大多数情况下是浏览或者编辑pdf信息,但有时候需要提取pdf中的文本,如果是单个文件的话还可以通过复制粘贴来直 ...
- 实用脚本!利用 Python 对 PDF 进行加密、解密操作,代码拿走就用!
来源/早起Python 本文将分享如何利用 Python 对 PDF 进行加密和解密操作,主要利用到之前多次介绍过的PyPDF2 模块. PDF 加密 在之前的文章PDF合并.拆分.水印.加密中简单提 ...
- 如何用python修改pdf内容_如何利用python将pdf文件转化为txt文件?
https://www.wukong.com/answer/6579491774144708872/?iid=15906422033&app=news_article&share_an ...
- 利用python将PDF转为PPT(课件专用)
利用python将PDF转为PPT(课件专用) 前言:课程中老师经常会将课件作为PDF发放而非PPT,而现有的PDF阅读器一般不支持添加修改等操作,所以显得十分麻烦,考虑将PDF转换为PPT格式,方便 ...
- 免费利用python把pdf格式转docx
免费利用python把pdf格式转docx,再也不用wps等要钱办公软件转文档了,不多说,直接上代码 1.首先导入pdf包,通过pip安装 pip install pdfplumber 2.开发代码上 ...
- python对PDF分割、合并、裁剪等
PyPDF2 PyPDF2是一个第三方的python PDF库,它能够对PDF文件进行分割.合并.裁剪和转换页面. 另外,它还可以对PDF文件添加自定义数据.水印.密码,也可以从PDF文件中检索出文本 ...
- python pdf报告_利用python设计PDF报告,jinja2,whtmltopdf,matplotlib,pandas
转自:https://foofish.net/python-crawler-html2pdf.html 工具准备 弄清楚了网站的基本结构后就可以开始准备爬虫所依赖的工具包了.requests.beau ...
- 利用 Python 去除 PDF 水印(和图片水印原理一样)
前言 今天介绍下用 Python 去除 PDF (图片)的水印.思路很简单,代码也很简洁. 首先来考虑 Python 如何去除图片的水印,然后再将思路复用到 PDF 上面. 原理 这张图片是前几天整理 ...
- python对excel筛选提取文本中数字_详解利用python提取pdf文本数字
之前也不乏介绍过关于excel的内容,日常工作应用,除了excel,pdf也是经常使用的一种,关于pdf的文本提取,下面也来详细介绍~ 说明:从pdf文件中提取其他类型的数据,如文本或图像.将说明从p ...
最新文章
- 第十九课.隐马尔科夫模型
- php try 并回滚,ThinkPHP异常处理、事务处理(事务回滚)
- Fastjson 1.2.68版本反序列化漏洞分析篇
- (转)Predictive learning vs. representation learning 预测学习 与 表示学习
- 二叉树介绍与代码实现
- Selenium自动化测试-4.By定位及如何确定元素唯一
- Error:java: Compilation failed: internal java compiler error
- Qt总结之十三:QUDPSocket详解
- 关闭MySQL日志,删除mysql-bin.0000*日志文件
- python控制安捷伦频谱仪_通过 python 对罗德施瓦茨矢网、信号源、频谱仪的控制...
- Benchmark tool library for c++ code
- 电视android降低版本,电视猫旧版本下载-电视猫视频去升级版3.1.3 安卓版下载_飞翔下载...
- wps表格的宏被禁用问题
- 破解大众点评 css加密
- 最新官方新浪短网址API接口分享-附代码调用演示
- 小熊派使SPI驱动TFT-LCD(ST7789)显示试验
- Codeforces 106C Buns - 多重背包 - 二进制拆分
- android临时文件夹,【报Bug】安卓端,保存视频到相册成功,临时文件夹中有,但是相册中没有...
- 资源收集贴(持续更新...)
- 使用python-opencv告警QObject::moveToThread