使用 Python 为 PDF 添加水印

概述

  1. 安装所需库
  2. 创建水印 PDF
  3. 将水印应用到你的 PDF

1. 安装所需库

首先,确保你的系统上安装了 Python。然后,使用 pip 安装必要的库:

pip install PyPDF2 reportlab
  • PyPDF2:一个用于读取和操作 PDF 文件的库。
  • reportlab:一个用于创建 PDF 文档的库,我们将使用它来创建水印。

2. 创建水印 PDF

我们将创建一个简单的水印 PDF,其中包含“CONFIDENTIAL”(机密)字样,以对角线形式覆盖在页面上。你可以根据需要自定义文本、字体、大小、颜色和位置。

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib import colorsdef create_watermark(watermark_text, watermark_pdf_path):c = canvas.Canvas(watermark_pdf_path, pagesize=letter)width, height = letter# 设置透明度(可选)c.setFillColor(colors.grey, alpha=0.3)# 设置字体和大小c.setFont("Helvetica-Bold", 50)# 旋转画布以绘制对角线文本c.saveState()c.translate(width / 2, height / 2)c.rotate(45)c.drawCentredString(0, 0, watermark_text)c.restoreState()c.save()if __name__ == "__main__":create_watermark("CONFIDENTIAL", "watermark.pdf")

解释:

  • canvas.Canvas:创建一个新的 PDF 画布。
  • setFillColor:设置文本颜色和透明度。
  • setFont:设置字体类型和大小。
  • saveState & restoreState:保存和恢复画布状态,以应用旋转等变换,而不影响后续的绘制。
  • translate & rotate:移动并旋转画布,以对角线形式定位文本。
  • drawCentredString:在指定位置居中绘制水印文本。

运行此脚本以生成 watermark.pdf

3. 将水印应用到你的 PDF

现在,我们将创建的水印应用到目标 PDF 的每一页。

import PyPDF2def add_watermark(input_pdf_path, output_pdf_path, watermark_pdf_path):# 打开原始 PDFwith open(input_pdf_path, 'rb') as input_file:reader = PyPDF2.PdfReader(input_file)writer = PyPDF2.PdfWriter()# 打开水印 PDFwith open(watermark_pdf_path, 'rb') as watermark_file:watermark = PyPDF2.PdfReader(watermark_file)watermark_page = watermark.pages[0]# 遍历所有页面并合并水印for page_number in range(len(reader.pages)):page = reader.pages[page_number]page.merge_page(watermark_page)writer.add_page(page)# 写出带水印的 PDFwith open(output_pdf_path, 'wb') as output_file:writer.write(output_file)if __name__ == "__main__":input_pdf = "input.pdf"          # 替换为你的输入 PDF 路径output_pdf = "watermarked.pdf"   # 期望的输出 PDF 路径watermark_pdf = "watermark.pdf"  # 我们之前创建的水印 PDFadd_watermark(input_pdf, output_pdf, watermark_pdf)print(f"带水印的 PDF 已保存为 {output_pdf}")

解释:

  1. 打开原始 PDF:使用 PyPDF2.PdfReader 读取输入 PDF。
  2. 打开水印 PDF:读取我们之前创建的水印 PDF。
  3. 将水印与每一页合并
    • 遍历原始 PDF 的每一页。
    • 使用 merge_page 将水印叠加到当前页。
    • 将合并后的页面添加到 PdfWriter 对象。
  4. 写出输出 PDF:将带水印的页面保存到新的 PDF 文件中。

注意事项:

  • 兼容性:确保水印 PDF 的页面大小与输入 PDF 相同,以避免缩放问题。
  • 透明度:水印 PDF 中设置的透明度确保水印不会过度遮挡原始内容。
  • 自定义:你可以通过修改 create_watermark 函数来调整水印的外观(例如更改文本、颜色、旋转角度)。

完整的工作流程示例

为了方便起见,以下是将上述两个步骤组合到一个脚本中的完整示例。此脚本首先创建水印,然后将其应用到目标 PDF。

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
import PyPDF2def create_watermark(watermark_text, watermark_pdf_path):c = canvas.Canvas(watermark_pdf_path, pagesize=letter)width, height = letter# 设置透明度(可选)c.setFillColor(colors.grey, alpha=0.3)# 设置字体和大小c.setFont("Helvetica-Bold", 50)# 旋转画布以绘制对角线文本c.saveState()c.translate(width / 2, height / 2)c.rotate(45)c.drawCentredString(0, 0, watermark_text)c.restoreState()c.save()def add_watermark(input_pdf_path, output_pdf_path, watermark_pdf_path):# 打开原始 PDFwith open(input_pdf_path, 'rb') as input_file:reader = PyPDF2.PdfReader(input_file)writer = PyPDF2.PdfWriter()# 打开水印 PDFwith open(watermark_pdf_path, 'rb') as watermark_file:watermark = PyPDF2.PdfReader(watermark_file)watermark_page = watermark.pages[0]# 遍历所有页面并合并水印for page_number in range(len(reader.pages)):page = reader.pages[page_number]page.merge_page(watermark_page)writer.add_page(page)# 写出带水印的 PDFwith open(output_pdf_path, 'wb') as output_file:writer.write(output_file)if __name__ == "__main__":# 参数watermark_text = "CONFIDENTIAL"watermark_pdf = "watermark.pdf"input_pdf = "input.pdf"          # 替换为你的输入 PDF 路径output_pdf = "watermarked.pdf"   # 期望的输出 PDF 路径# 创建水印create_watermark(watermark_text, watermark_pdf)print(f"水印 PDF '{watermark_pdf}' 已创建。")# 将水印添加到 PDFadd_watermark(input_pdf, output_pdf, watermark_pdf)print(f"带水印的 PDF 已保存为 '{output_pdf}'。")

使用方法:

  1. 准备你的输入 PDF:确保在脚本所在的目录中有 input.pdf,或提供正确的路径。
  2. 运行脚本:使用 Python 执行脚本。
python add_watermark.py

运行后,你将获得一个名为 watermarked.pdf 的文件,每一页上都带有“CONFIDENTIAL”水印。

额外提示

  • 每页不同的水印:如果你想在不同的页面上使用不同的水印,可以修改 add_watermark 函数以处理多个水印 PDF 或动态生成它们。
  • 定位:通过调整 create_watermark 函数中的 translaterotate 参数,可以改变水印的位置和角度。
  • 多个水印:你可以通过在每个 PDF 页面上合并多个水印页面来叠加多个水印。
  • 错误处理:对于生产环境的脚本,建议添加错误处理,以管理诸如文件缺失或 PDF 格式不兼容等问题。

替代库

虽然 PyPDF2reportlab 功能强大且广泛使用,但你可能还会考虑以下替代库:

  • PyMuPDF (fitz):一个快速且多功能的 PDF 操作库。

    pip install PyMuPDF
    
  • pdfplumber:主要用于提取信息,但可以与其他库结合使用进行操作。

  • pdfrw:另一个用于读取和写入 PDF 的库,通常与 reportlab 一起使用。

根据你的项目需求和熟悉程度,选择最适合的库。

结论

通过遵循上述步骤,你可以高效地使用 Python 为 PDF 文档添加水印。这种方法具有高度的可定制性,并且可以根据需要集成到更大的自动化工作流程中。如果你遇到任何问题或有进一步的问题,请随时提问!

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

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

相关文章

数据库管理-第275期 Oracle 23ai:画了两张架构图(20241225)

数据库管理275期 2024-12-25 数据库管理-第275期 Oracle 23ai:画了两张架构图(20241225)1 系统管理分片2 用户定义分片总结 数据库管理-第275期 Oracle 23ai:画了两张架构图(20241225) 作者:胖…

增强路由器 路由器升级宽带速度

由器中DNS设置 DNS(域名系统)是什么? DNS将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。DNS使用UDP端口53。 上网前提是:配置 IPv4地址、子网掩码 、网关、DNS 正确才能够上网 DNS填写规…

stm32制作CAN适配器5--WinUsb上位机编写

上次我们要stm32制作了一个基于winusb有canfd适配器,今天我们来制作一个上位机程序来进行报文收发。 上位机还是用以前写好的,只是更改下dll文件。 项目链接器,输入,附加依赖项中增加winusb.lib winusb初始化:#incl…

谷歌浏览器 Chrome 提示:此扩展程序可能很快将不再受支持

问题现象 在Chrome 高版本上的扩展管理页面(地址栏输入chrome://extensions/或者从界面进入): , 可以查看到扩展的情况。 问题现象大致如图: 问题原因 出现此问题的根本原因在于:谷歌浏览器本身的扩展机制发生了…

Vue.js组件(6):echarts组件

1 前言 本章主要对常用的echars图表展示进行基本的组件封装。使用该组件前需要在项目中引入echarts。官网:Apache ECharts npm install echarts --save 2 图表组件 2.1 折线图组件 组件属性:chartId,指定图表挂载div的id,注意不…

MySQL用表组织数据

用表组织数据 文章目录 用表组织数据一.四种完整性约束二.数值类型2-1三.数值类型2-2四.字符串.日期类型五.设置1.设置主键2.设置标识列3.设置非空4.设置默认值 六.主外键建立后注意事项 一.四种完整性约束 1.域完整性 列 域完整性约束方法:限制数据类型,检查约束,外键约束,默…

面试经典问题 —— 最大/小前K个数问题(top - K)问题

目录 常见思路更优的解法(面试官喜欢的) 常见思路 要选出最小的前K个数首先我们会想到排排升序建大堆,排降序建小堆 一个直观的想法是使用(小根堆),起始将所有元素放入堆中,然后再从堆中取出k 个…

外包干了27天,技术退步明显。。。。。

时光荏苒,转眼我已是一个拥有近四年功能测试经验的大专生。20年,我满怀激情地通过校招进入湖南某知名软件公司,期待在这里开启我的职业生涯。然而,长时间的舒适环境让我渐渐失去了前进的动力,技术停滞不前,…

从自动驾驶到具身智能漫谈

0. 简介 从作者的眼光来看自动驾驶和具身智能已经是越来越接近了。无论是技术栈以及实现的最终目的。其实都是希望人在环内。这个是古月直播的文字相关的大致梳理。主要会展开聊一聊自动驾驶的变迁以及作为自动驾驶的从业人员要着重关注的一些技术点 1. 自动驾驶的变迁 在自…

Excel粘贴复制不完整的原因以及解决方法

在数据处理和分析的过程中,Excel无疑是不可或缺的工具。然而,在使用Excel进行复制粘贴操作时,有时会遇到粘贴不完整的情况,这可能会让人感到困惑和烦恼。本文将深入探讨Excel粘贴复制不完整的原因、提供解决方案,并给出…

云原生之docker详解

目录 1.云原生概念 1.1 云原生定义 1.2 云原生元素 1.2.1 微服务 1.2.2 DevOps 1.2.3 持续交付 1.2.4 容器化 2. Docker 2.1 Docker概述 2.1.1 Docker 定义 2.1.2 Docker应用场景 2.1.3 Docker的架构 2.2 Docker命令 2.2.1 docker进程相关命令 2.2.2 docker镜像…

数仓开发那些事(8)

程序员圣经 为什么刚刚能运行,现在就不行 为什么刚刚不运行,现在就可以 为什么他的可以跑,我的不能跑 为什么我的可以跑,他的就不行 为什么这台电脑能,那台就不行 为什么这台电脑不行,那台就行 神州员工&a…

在UE5中调用ImGui图形界面库

ImGui是一个小巧灵活、简洁美观的图形界面库 首先我们直接参考Github https://github.com/SLSNe/Unreal5-ImGui 把项目下载下来后 打开项目目录或者引擎目录 项目根目录/Plugins/ImGui/ 或 UE5引擎根目录/Engine/Plugins/ 如果没有Plugins文件夹就新建一个 把项目放里面…

华为管理变革之道:奋斗文化与活力

目录 企业文化是什么? 为什么活下去是华为的文化? 活下来,是华为公司的最低纲领,也是华为公司的最高纲领! 资源终会枯竭,唯有文化才能生生不息 企业文化之一:以客户为中心 企业文化之二&a…

JZ31 栈的压入、弹出序列

题目来源:栈的压入、弹出序列_牛客题霸_牛客网 题目:如下 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序&#xf…

(echarts)数据地图散点类型根据条件设置不同的标记图片

(echarts)数据地图散点类型根据条件设置不同的标记图片 1.用在线工具将本地图片转化base64格式 data(){return { base64Img:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQ...",} }在线转换地址:https://www.jyshare.com/front-end/59/ 2.symbol属…

ArcGIS+MIKE21 洪水淹没分析、溃坝分析,洪水淹没动态效果

洪水淹没分析过程: 一、所需数据: 1.分析区域DEM数据 二、ArcGIS软件 1.提取分析区域DEM(水库坝下区域) 2.DEM栅格转点 3.计算转换后几何点的x和y坐标值(精度20、小数位3) 4.导出属性表,形式…

LSTM-SVM时序预测 | Matlab基于LSTM-SVM基于长短期记忆神经网络-支持向量机时间序列预测

LSTM-SVM时序预测 | Matlab基于LSTM-SVM基于长短期记忆神经网络-支持向量机时间序列预测 目录 LSTM-SVM时序预测 | Matlab基于LSTM-SVM基于长短期记忆神经网络-支持向量机时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.LSTM-SVM时序预测 | Matlab基于LSTM…

虚拟机桥接模式网络连接不上解决方法

可能是桥接模式自动配置网络地址的时候没配好,自己手动配置一下。先看看windows里的wifi的ip 把虚拟机的网络设置打开ipv4把地址、子网掩码、网关输进去,然后再连接

家用无线路由器的 2.4GHz 和 5GHz

家中的无线路由器 WiFi 名称有两个,一个后面带有 “5G” 的标记,这让人产生疑问:“连接带‘5G’的 WiFi 是不是速度更快?” 实际上,这里的 “5G” 并不是移动通信中的 5G 网络,而是指路由器的工作频率为 5G…