当前位置: 首页 > news >正文

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度后保存到该文件中。原始文件如下:

截屏2024-10-09 19.17.13

下面将以上的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)

运行结果如下图:

在这里插入图片描述

代码解释

  1. 导入模块:
    • from pathlib import Path: 导入 Path 类,以方便处理文件路径。
    • from PyPDF2 import PdfReader, PdfWriter: 从 PyPDF2 导入 PdfReaderPdfWriter 类,用于读取和写入 PDF 文件。
  2. 定义 PDF 文件路径:
    • pdf_path = Path.cwd() / 'practice_files' / 'split_and_rotate.pdf': 使用 Path.cwd() 获取当前工作目录,并与 'practice_files''split_and_rotate.pdf' 连接,构建出完整的 PDF 文件路径。
  3. 读取 PDF 文件:
    • pdf_reader = PdfReader(str(pdf_path)): 使用 PdfReader 类实例化一个对象 pdf_reader,读取指定路径的 PDF 文件。此时,pdf_reader 包含了所有页面的信息。
  4. 创建 PDF 写入器:
    • pdf_writer = PdfWriter(): 实例化一个 PdfWriter 对象,用于创建新的 PDF 文件并写入内容。
  5. 遍历 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 对象中。
  6. 写入新的 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)

运行结果如下:

截屏2024-10-09 19.30.03

代码解释

  1. 导入模块:
    • from pathlib import Path: 导入 Path 类,用于处理文件路径。
    • from PyPDF2 import PdfWriter, PdfReader: 从 PyPDF2 中导入 PdfWriterPdfReader,用于读取和生成 PDF 文件。
    • import copy: 导入 copy 模块,以便可以进行深拷贝操作。
  2. 定义 PDF 文件路径:
    • pdf_path = (Path.home() / 'rotated.pdf'): 使用 Path.home() 获取用户主目录,并与 'rotated.pdf' 拼接,构建出完整的 PDF 文件路径。
  3. 读取 PDF 文件:
    • pdf_reader = PdfReader(str(pdf_path)): 实例化一个 PdfReader 对象,读取指定路径的 PDF 文件。这将把文件中的所有页面信息加载到内存中。
  4. 创建 PDF 写入器:
    • pdf_writer = PdfWriter(): 实例化一个 PdfWriter 对象,用于创建新的 PDF 文件并写入内容。
  5. 获取页面坐标:
    • current_coords = pdf_reader.pages[0].mediabox.upper_right: 获取 PDF 的第一个页面的右上角坐标,这个坐标用于确定后续生成的两部分的尺寸。
  6. 遍历 PDF 文件中的每一页:
    • for page in pdf_reader.pages:: 遍历所有页面。
  7. 创建页面的深拷贝:
    • left_side = copy.deepcopy(page): 创建当前页面的一个深拷贝,用于生成左半边页面。
    • right_side = copy.deepcopy(page): 同样深拷贝当前页面,用于生成右半边页面。
  8. 计算新坐标:
    • new_coords = (current_coords[0] / 2, current_coords[1]): 将右上角的 X 坐标除以 2,保留 Y 坐标不变,计算出左半边和右半边的新边界坐标。
  9. 设置左右页面的坐标:
    • left_side.mediabox.upper_right = new_coords: 更新左半边页面的右上角坐标。
    • right_side.mediabox.upper_left = new_coords: 更新右半边页面的左上角坐标。
  10. 写入修改后的页面:
    • pdf_writer.add_page(left_side): 将左半边页面添加到 PDF 写入器。
    • pdf_writer.add_page(right_side): 将右半边页面也添加到 PDF 写入器。
  11. 输出新的 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&#xff1…...

【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)是机器学习中的一个前沿领域,它涉及处理和整合来自多个数据模式(如图像、文本、音频等)的信息。随着深度学习的蓬勃发展&#xff0…...

​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着色模型)

快速导航&#xff08;持续更新中&#xff09; WebGL系列教程一&#xff08;开篇&#xff09; WebGL系列教程二&#xff08;环境搭建及着色器初始化&#xff09; WebGL系列教程三&#xff08;使用缓冲区绘制三角形&#xff09; WebGL系列教程四&#xff08;绘制彩色三角形&…...

《ASP.NET Web Forms 实现短视频点赞功能的完整示例》

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

Linux SSH服务

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

MySQL--视图(详解)

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

Javascript 普通非async函数调用async函数

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

【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" 有什么区别&#xff1f; ‌‌‌‌  对于 #include <filename> &#xff0c; 编译器从标准库路径开始搜索 filename.h。 ‌‌‌‌  对于 #include "filename.h&#xff0c;编译器从用户的工作…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...