Python对PDF文件页面的旋转和切割
Python对PDF文件页面的旋转和切割
利用Python的.rotate()方法和.mediabox属性对PDF页面进行旋转和切割,最终生成一个PDF。下面结合案例进行说明,本示例中的名为split_and_rotate.pdf文件在practice_files文件夹中,
示例(1):
在home目录中创建一个新的PDF,命名为rotated.pdf。将split_and_rotate.pdf中的所有页面逆时针旋转90度后保存到该文件中。原始文件如下:
下面将以上的PDF文件逆时针旋转90度后保存。
源代码如下:
from pathlib import Path
from PyPDF2 import PdfReader, PdfWriter# 定义 PDF 文件的路径,位置在当前工作目录下的 'practice_files' 文件夹中
pdf_path = Path.cwd() / 'practice_files' / 'split_and_rotate.pdf'# 读取指定路径的 PDF 文件
pdf_reader = PdfReader(str(pdf_path))# 创建一个 PDF 写入器对象,用于写入新的 PDF 文件
pdf_writer = PdfWriter()# 遍历 PDF 文件中的每一页
for page in range(len(pdf_reader.pages)):# 将当前页面旋转 -90 度,并添加到写入器中pdf_writer.add_page(pdf_reader.pages[page].rotate(-90))# 在用户的主目录下创建一个新的 PDF 文件 'rotated.pdf',以写入模式打开
with (Path.home() / 'rotated.pdf').open('wb') as f:# 将合并后的内容写入到新创建的文件中pdf_writer.write(f)
运行结果如下图:
代码解释
- 导入模块:
from pathlib import Path
: 导入Path
类,以方便处理文件路径。from PyPDF2 import PdfReader, PdfWriter
: 从PyPDF2
导入PdfReader
和PdfWriter
类,用于读取和写入 PDF 文件。
- 定义 PDF 文件路径:
pdf_path = Path.cwd() / 'practice_files' / 'split_and_rotate.pdf'
: 使用Path.cwd()
获取当前工作目录,并与'practice_files'
和'split_and_rotate.pdf'
连接,构建出完整的 PDF 文件路径。
- 读取 PDF 文件:
pdf_reader = PdfReader(str(pdf_path))
: 使用PdfReader
类实例化一个对象pdf_reader
,读取指定路径的 PDF 文件。此时,pdf_reader
包含了所有页面的信息。
- 创建 PDF 写入器:
pdf_writer = PdfWriter()
: 实例化一个PdfWriter
对象,用于创建新的 PDF 文件并写入内容。
- 遍历 PDF 文件的每一页:
for page in range(len(pdf_reader.pages))
: 使用循环遍历pdf_reader
中的每一页,len(pdf_reader.pages)
返回 PDF 文件的总页数。pdf_writer.add_page(pdf_reader.pages[page].rotate(-90))
: 取出当前页 (pdf_reader.pages[page]
),调用rotate(-90)
方法将该页旋转 -90 度(向左旋转),然后使用add_page()
方法将旋转后的页面添加到pdf_writer
对象中。
- 写入新的 PDF 文件:
with (Path.home() / 'rotated.pdf').open('wb') as f
: 在用户的主目录下创建一个新的 PDF 文件,命名为rotated.pdf
,以二进制写入模式打开它。pdf_writer.write(f)
: 将pdf_writer
中的内容写入到新创建的rotated.pdf
文件中,完成旋转操作后的 PDF 文件创建。
示例(2):
使用示例(1)中创建的rotated.pdf,将PDF中的每一页沿垂直中线分割开来,在home目录中创建一个新的PDF,命名为split.pdf。将分割后得到的页面保存在该文件中。示例源码如下:
from pathlib import Path
from PyPDF2 import PdfWriter, PdfReader
import copy# 定义 PDF 文件的路径,位置在用户的主目录下,文件名为 'rotated.pdf'
pdf_path = (Path.home() / 'rotated.pdf')# 读取指定路径的 PDF 文件
pdf_reader = PdfReader(str(pdf_path))
# 创建一个 PDF 写入器对象,用于写入新的 PDF 文件
pdf_writer = PdfWriter()# 获取第一个页面的右上角坐标
current_coords = pdf_reader.pages[0].mediabox.upper_right
# 遍历 PDF 文件中的每一页
for page in pdf_reader.pages:# 深拷贝当前页面,以创建左半边和右半边left_side = copy.deepcopy(page)right_side = copy.deepcopy(page)# 计算新坐标,将右上角的 X 坐标除以 2,Y 坐标保持不变new_coords = (current_coords[0] / 2, current_coords[1])# 设置左半边的右上角坐标为新坐标left_side.mediabox.upper_right = new_coords# 设置右半边的左上角坐标为新坐标right_side.mediabox.upper_left = new_coords# 将修改后的左半边页面添加到写入器中pdf_writer.add_page(left_side)# 将修改后的右半边页面也添加到写入器中pdf_writer.add_page(right_side)# 在当前工作目录下创建一个新的 PDF 文件 'split.pdf',以写入模式打开
with Path.cwd().joinpath('split.pdf').open('wb') as f:# 将合并后的内容写入到新创建的文件中pdf_writer.write(f)
运行结果如下:
代码解释
- 导入模块:
from pathlib import Path
: 导入Path
类,用于处理文件路径。from PyPDF2 import PdfWriter, PdfReader
: 从PyPDF2
中导入PdfWriter
和PdfReader
,用于读取和生成 PDF 文件。import copy
: 导入copy
模块,以便可以进行深拷贝操作。
- 定义 PDF 文件路径:
pdf_path = (Path.home() / 'rotated.pdf')
: 使用Path.home()
获取用户主目录,并与'rotated.pdf'
拼接,构建出完整的 PDF 文件路径。
- 读取 PDF 文件:
pdf_reader = PdfReader(str(pdf_path))
: 实例化一个PdfReader
对象,读取指定路径的 PDF 文件。这将把文件中的所有页面信息加载到内存中。
- 创建 PDF 写入器:
pdf_writer = PdfWriter()
: 实例化一个PdfWriter
对象,用于创建新的 PDF 文件并写入内容。
- 获取页面坐标:
current_coords = pdf_reader.pages[0].mediabox.upper_right
: 获取 PDF 的第一个页面的右上角坐标,这个坐标用于确定后续生成的两部分的尺寸。
- 遍历 PDF 文件中的每一页:
for page in pdf_reader.pages:
: 遍历所有页面。
- 创建页面的深拷贝:
left_side = copy.deepcopy(page)
: 创建当前页面的一个深拷贝,用于生成左半边页面。right_side = copy.deepcopy(page)
: 同样深拷贝当前页面,用于生成右半边页面。
- 计算新坐标:
new_coords = (current_coords[0] / 2, current_coords[1])
: 将右上角的 X 坐标除以 2,保留 Y 坐标不变,计算出左半边和右半边的新边界坐标。
- 设置左右页面的坐标:
left_side.mediabox.upper_right = new_coords
: 更新左半边页面的右上角坐标。right_side.mediabox.upper_left = new_coords
: 更新右半边页面的左上角坐标。
- 写入修改后的页面:
pdf_writer.add_page(left_side)
: 将左半边页面添加到 PDF 写入器。pdf_writer.add_page(right_side)
: 将右半边页面也添加到 PDF 写入器。
- 输出新的 PDF 文件:
with Path.cwd().joinpath('split.pdf').open('wb') as f
: 创建一个新的 PDF 文件,命名为split.pdf
,在当前工作目录下,以二进制写入模式打开。pdf_writer.write(f)
: 将写入器中的内容(即左半边和右半边的页面)写入到新创建的split.pdf
文件中。
希望此文对您有所启发和帮助,欢迎点赞、关注、转发!!!
相关文章:

Python对PDF文件页面的旋转和切割
Python对PDF文件页面的旋转和切割 利用Python的.rotate()方法和.mediabox属性对PDF页面进行旋转和切割,最终生成一个PDF。下面结合案例进行说明,本示例中的名为split_and_rotate.pdf文件在practice_files文件夹中, 示例(1&#…...

Android 10.0 修改Systemui三键导航栏虚拟按键颜色功能实现
1.前言 在10.0的系统ROM定制化开发中,在对systemui的相关定制化开发中,在某些产品中,需要修改相关的 导航栏三键导航的虚拟按键的颜色,修改掉原来默认的虚拟按键的黑白色,接下来就来实现相关的功能 2.修改Systemui三键导航栏虚拟按键颜色功能实现的核心类 frameworks\ba…...

『网络游戏』客户端使用PESorket发送消息到服务器【14】
上一章服务器已经完成使用PESorket 现在我们将其导出在客户端中使用 生成成功后复制 粘贴到Unity项目中 进入Assets文件夹 粘贴两个.dll 创建脚本:ClientSession.cs 编写脚本: ClientSession.cs 编写脚本:GameStart.cs 将GameStart.cs脚本绑定在摄像机上 运行服务器 运行客户端…...

JVM(学习预热 - 走进Java)(持续更新迭代)
目录 一、彻底认识Java虚拟机 开创世纪:Sun Classic 开创世纪:Exact VM 武林霸主:HotSpot VM 移动端虚拟机:Mobile/Embedded VM “三大”其二:BEA JRockit/IBM J9 VM 软硬结合:BEA Liquid VM/Azul VM…...

43 C 程序动态内存分配:内存区域划分、void 指针、内存分配相关函数(malloc、calloc、realloc、_msize、free)、内存泄漏
目录 1 C 程序内存区域划分 1.1 代码区 (Code Section) 1.2 全局/静态区 (Global/Static Section) 1.3 栈区 (Stack Section) 1.4 堆区 (Heap Section) 1.5 动态内存分配 2 void 指针(无类型指针) 2.1 void 指针介绍 2.2 void 指针的作用 2.3 …...

编译链接的过程发生了什么?
一:程序的翻译环境和执行环境 在 ANSI C 的任何一种实现中,存在两个不同的环境。 第 1 种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。 第 2 种是执行环境,它用于实际执行代码 也就是说:↓ 1࿱…...

【D3.js in Action 3 精译_028】3.4 小节 DIY 实战:使用 Observable 在线绘制 D3 条形图
当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一部分 D3.js 基础知识 第一章 D3.js 简介(已完结) 1.1 何为 D3.js?1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践(上)1.3 数据可…...

【Linux】 TCP短服务编写和守护进程
文章目录 TCP 短服务编写流程进程组和会话和守护进程 TCP 短服务编写流程 TCP服务器是面向连接的,客户端在发送数据之前需要先与服务器建立连接。 因此,TCP服务器需要能够监听客户端的连接请求。为了实现这一功能,需要将TCP服务器创建的套接字…...

自学数据库-MYSQL
自学数据库-MYSQL 一.表和视图1.表1.1 表创建1.2 索引1.2.1 这里是废话,不感兴趣的可以直接更具目录的跳过这里的内容1.2.1.1 索引是什么1.2.1.2 相关数据结构:二叉树、红黑树、B-Tree、BTree、Hash…①普通索引②唯一索引③全文索引④组合索引 1.3 表数据操作(更新…...

机器学习——多模态学习
多模态学习:机器学习领域的新视野 引言 多模态学习(Multimodal Learning)是机器学习中的一个前沿领域,它涉及处理和整合来自多个数据模式(如图像、文本、音频等)的信息。随着深度学习的蓬勃发展࿰…...

ceph掉电后无法启动osd,pgs unknown
处理办法: 只有1个osd,单副本,掉电损坏osd,只能考虑重建pg,丢失部分数据了。生产环境务必考虑2,3副本设计。避免掉电故障风险。 掉电后osdmap丢失无法启动osd的解决方案 - 武汉-磨渣 - 博客园 https://zhuanlan.zhih…...

HTML5实现古典音乐网站源码模板1
文章目录 1.设计来源1.1 网站首页1.2 古典音乐界面1.3 著名人物界面1.4 古典乐器界面1.5 历史起源界面2.效果和源码2.1 动态效果2.2 源代码源码下载万套模板,程序开发,在线开发,在线沟通作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/142…...

快速生成单元测试
1. Squaretest插件 2. 依赖 <dependency><groupId>junit</groupId>...

WebGL系列教程十一(光照原理及Blinn Phong着色模型)
快速导航(持续更新中) WebGL系列教程一(开篇) WebGL系列教程二(环境搭建及着色器初始化) WebGL系列教程三(使用缓冲区绘制三角形) WebGL系列教程四(绘制彩色三角形&…...

《ASP.NET Web Forms 实现短视频点赞功能的完整示例》
在现代Web开发中,实现一个动态的点赞功能是非常常见的需求。本文将详细介绍如何在ASP.NET Web Forms中实现一个视频点赞功能,包括前端页面的展示和后端的处理逻辑。我们将确保点赞数量能够实时更新,而无需刷新整个页面。 技术栈 ASP.NET We…...

Linux SSH服务
Linux SSH(Secure Shell)服务是一种安全的远程登录协议,用于在Linux操作系统上远程登录和执行命令。它提供了加密的通信通道,可以在不安全的网络环境中安全地进行远程访问。 SSH服务在Linux系统中通常使用OpenSSH软件包来实现。它…...

MySQL--视图(详解)
目录 一、前言二、视图2.1概念2.2语法2.3创建视图2.3.1目的 2.4查看视图2.5修改数据2.5.1通过真实表修改数据,会影响视图2.5.2通过修改视图,会影响基表 2.6注意2.7 删除视图2.8 视图的优点 一、前言 欢迎大家来到权权的博客~欢迎大家对我的博客进行指导&…...

Javascript 普通非async函数调用async函数
假设我们有一个异步函数 async function asyncFunction() {console.log("开始执行异步函数");await new Promise(resolve > setTimeout(resolve, 1000)); // 模拟异步操作console.log("异步函数执行完毕"); } 我们在调用这个异步函数时,比…...

【LeetCode】修炼之路-0004-Median of Two Sorted Arrays【python】
题目 Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. The overall run time complexity should be O(log (mn)). Example 1: Input: nums1 [1,3], nums2 [2] Output: 2.00000 Explanation: merged…...

C++面试速通宝典——10
177. #include <filename> 和 #include "filname.h" 有什么区别? 对于 #include <filename> , 编译器从标准库路径开始搜索 filename.h。 对于 #include "filename.h,编译器从用户的工作…...

肺腺癌预后新指标:全切片图像中三级淋巴结构密度的自动化量化|文献精析·24-10-09
小罗碎碎念 本期这篇文章,我去年分享过一次。当时发表在知乎上,没有标记参考文献,配图的清晰度也不够,并且分析的还不透彻,所以趁着国庆假期重新分析一下。 这篇文章的标题为《Computerized tertiary lymphoid structu…...

基于jmeter+perfmon的稳定性测试记录
1. 引子 最近承接了项目中一些性能测试的任务,因此决定记录一下,将测试的过程和一些心得收录下来。 说起来性能测试算是软件测试行业内,有些特殊的部分。这部分的测试活动,与传统的测试任务差别是比较大的,也比较依赖…...

前沿论文 M5Product 组会 PPT
对比学习(Contrast learning):对比学习是一种自监督学习方法,用于在没有标签的情况下,通过让模型学习哪些数据点相似或不同来学习数据集的一般特征。假设一个试图理解世界的新生婴儿。在家里,假设有两只猫和…...

navicat~导出数据库密码
当我们mysql密码忘记了,而在navicat里有记录,我们应该如何导出这个密码呢? 第一步:文件菜单,导出链接,导出连接获取到 connections.ncx 文件 这里需要勾选 导出密码!!! 不然导出的文…...

【Java】 —— 数据结构与集合源码:Vector、LinkedList在JDK8中的源码剖析
目录 7.2.4 Vector部分源码分析 7.3 链表LinkedList 7.3.1 链表与动态数组的区别 7.3.2 LinkedList源码分析 启示与开发建议 7.2.4 Vector部分源码分析 jdk1.8.0_271中: //属性 protected Object[] elementData; protected int elementCount;//构造器 public …...

YOLOv5改进——添加SimAM注意力机制
目录 一、SimAM注意力机制核心代码 二、修改common.py 三、修改yolo.py 三、建立yaml文件 四、验证 一、SimAM注意力机制核心代码 在models文件夹下新建modules文件夹,在modules文件夹下新建一个py文件。这里为simam.py。复制以下代码到文件里面。 import…...

SQL 自学:表别名的运用与对被联结表使用聚集函数
一、表别名的概念与作用 (一)表别名的定义 表别名是为表指定的临时名称,在 SQL 查询中使用别名可以简化表名,提高代码的可读性和可维护性。当表名较长或在复杂的查询中多次引用表时,使用表别名可以避免重复输入冗长的…...

jmeter学习(2)变量
1)用户定义的变量 路径:添加-》配置元件-》用户定义的变量 用户定义的变量是全局变量,可以跨线程组被调用,但在启动运行时获取一次值,在运行过程中不再动态获取值。 注意的是,如果在某个线程组定义了全…...

【C#生态园】C#文件压缩库全面比较:选择最适合你的库
从核心功能到API概览:深度解析六大C#文件压缩库 前言 在软件开发过程中,文件的压缩和解压缩是一个常见的需求。针对C#开发者而言,选择合适的文件压缩库可以极大地简化开发工作。本文将介绍几个常用的C#文件压缩库,包括其核心功能…...

【测试】接口测试与接口自动化
壹、接口测试基础 一、接口测试概念 I、基础概念 是测试系统组件间接口的一种测试。 主要用于检测外部系统与系统间、内部子系统间的交互点;测试重点检查数据的交换、传递和控制管理过程,以及系统间的相互逻辑依赖关系。 内部接口调用相当于函数调用&am…...