Python对PDF文件页面的旋转和切割

news2024/11/27 11:35:59

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 文件中。

希望此文对您有所启发和帮助,欢迎点赞、关注、转发!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2201594.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ShardingSphere分库分表产品介绍

目录 一、ShardingSphere分库分表产品介绍 二、客户端分库分表与服务端分库分表 1、ShardingJDBC客户端分库分表 2、ShardingProxy服务端分库分表 3、ShardingSphere混合部署架构 三、分库分表,能不分就不分! 1、为什么要分库分表? 2、…

基于SpringBoot点餐系统【附源码】

基于SpringBoot点餐系统 效果如下: 系统首页界面 用户注册界面 美食信息页面 促销活动页面 管理员登录主页面 系统管理界面 订单管理界面 研究背景 随着互联网的迅猛发展和人们生活节奏的加快,传统的点餐方式已经无法满足现代消费者对快速、便捷服务的…

解决银河麒麟操作系统中无法通过管理员安装软件或运行有执行权限脚本的问题

解决银河麒麟操作系统中无法通过管理员安装软件或运行有执行权限脚本的问题 1、问题描述2、问题分析3、问题解决方法 💐The Begin💐点点关注,收藏不迷路💐 1、问题描述 在银河麒麟操作系统中,通过终端执行命令时&…

103页PPT | 智慧城市综合解决方案

智慧城市概况 PPT开篇介绍了智慧城市的发展历程,从2014年国家提出《国家新型城镇化规划(2014-2020年)》开始,到2017年提出从“智慧城市”到“新型智慧城市”的转变,再到2020年新型智慧城市建设取得显著成效。这一过程中&#xff…

3.1 显示层技术演变

文章目录 静态网站公共网关接口CGIServletJSPJSP模板引擎第三方模板引擎前后端分离Thymeleaf 今天我将与大家分享显示层技术的演变历程,以及它们在现代Web开发中的应用。 静态网站 首先,我们从静态网站开始。静态网站主要由HTML、CSS和JavaScript等静态…

JimuReport报表部署 | 升级 | 仪表盘集成 | 迁移其他项目 (图文讲解)

目录 前言1. 项目部署2. 项目升级3. 仪表盘集成3.1 配置类事项3.2 版本升级事项4. 迁移到ruoyi-vue-pro4.1 权限4.2 前端5. 彩蛋前言 以下针对Vue以及Java的项目 对于文中所说的nginx以及Java的相关知识推荐阅读: java框架 零基础从入门到精通的学习路线 附开源项目面经等(…

冷热数据分离

优质博文:IT-BLOG-CN 一、背景 随着机票业务的快速发展,订单量持续增长对业务性能带来影响,需要进行冷热数据分离。目前机票订单模块主要使用Mysql(InnoDB)作为数据库存储,历史订单信息状态修改频率低并占用大量数据库存储空间&…

第69期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区,集成了生成预训练Transformer(GPT)、人工智能生成内容(AIGC)以及大语言模型(LLM)等安全领域应用的知识。在这里,您可以找…

LeetCode 1928.规定时间内到达终点的最小花费:动态规划

【LetMeFly】1928.规定时间内到达终点的最小花费:动态规划 力扣题目链接:https://leetcode.cn/problems/minimum-cost-to-reach-destination-in-time/ 一个国家有 n 个城市,城市编号为 0 到 n - 1 ,题目保证 所有城市 都由双向道…

Apache DolphinScheduler社区9月进展记录

各位热爱 Apache DolphinScheduler 的小伙伴们,社区 9 月月报更新啦!这里将记录 Apache DolphinScheduler 社区每月的重要更新,欢迎关注! 月度 Merge Star 感谢以下小伙伴上个月为 Apache DolphinScheduler 做的精彩贡献&#x…

数据结构前置知识(上)

1. 初识集合框架 1.1 什么是集合框架 在了解集合框架之前,我们先来认识一下数据结构,所谓数据结构就是描述和组织数据的一个东西. 那什么是集合框架呢?在java里面集合框架(Java Collection Framework),又被称为容器container,说白了就是很多个接口,抽象类,实现类组成的一个包,…

Node脚本实现批量打包Vue项目(child_process子进程、window)

前言 前几天用pnpmworkspace实现了monorepo,也就是单仓库多个项目,并且互相之间可能存在一定的联系。所以就存在一个打包的问题,也就是说,我想在打包某个特定子项目时,其他项目也执行build的命令。主要用到的是node的…

字节跳动推机器人大模型GR-2 展现智能自主操作新高度

字节跳动研究团队近日推出的第二代机器人大模型GR-2(Generative Robot2.0)正在引发业界广泛关注。这款智能机器人不仅标志着机器人大模型技术的重大突破,更预示着智能机器人应用即将迎来一个全新纪元。 GR-2的独特之处在于其创新的学习方式。…

力扣之1355.活动参与者

题目: Sql 测试用例: Create table If Not Exists Friends (id int, name varchar(30), activity varchar(30)); Create table If Not Exists Activities (id int, name varchar(30)); Truncate table Friends; insert into Friends (id, name, acti…

FreeRTOS学习总结

背景:在裸机开发上,有时候我们需要等待某个信号或者需要延迟时,CPU的运算是白白浪费掉了的,CPU的利用率并不高,我们希望当一个函数在等待的时候,可以去执行其他内容,提高CPU的效率,同…

朝花夕拾:多模态图文预训练的前世今生

Diffusion Models专栏文章汇总:入门与实战 前言:时间来到2024年,多模态大模型炙手可热。在上一个时代的【多模态图文预训练】宛若时代的遗珠,本文的时间线从2019年到2022年,从BERT横空出世讲到ViT大杀四方,…

通过阿里云Milvus与PAI搭建高效的检索增强对话系统

阿里云Milvus现已无缝集成于阿里云PAI平台,一站式赋能用户构建高性能的RAG(Retrieval-Augmented Generation)对话系统。您可以利用Milvus作为向量数据的实时存储与检索核心,高效结合PAI和LangChain技术栈,实现从理论到…

数学建模算法与应用 第8章 时间序列分析

目录 8.1 确定性时间序列分析方法 Matlab代码示例:移动平均法提取趋势 8.2 平稳时间序列模型 Matlab代码示例:差分法与ADF检验 8.3 时间序列的Matlab相关工具箱及命令 Matlab代码示例:ARIMA模型的建立 8.4 ARIMA序列与季节性序列 Matl…

【Golang】Go语言中缓冲bufio的原理解读与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

Ubuntu关闭anaconda自动进入base虚拟环境

问题描述:安装好Anconda后,每次打开终端后都会自动进入到base的虚拟环境中去 直接使用通常情况下也不会有什么影响,但是为了避免,有以下两个方法: 1.使用conda deactivate #每次使用conda deactivate,退…