今天介绍下用 Python 去除 PDF (图片)的水印。思路很简单,代码也很简洁。

首先来考虑 Python 如何去除图片的水印,然后再将思路复用到 PDF 上面。

这张图片是前几天整理《数据结构和算法》PDF里的一个截图,带着公众号的水印。

从上图可以明显看到,为了不影响阅读正文,水印颜色一般比较浅。因此,我们可以利用颜色差这个特征来去掉水印。即:用 Python 读取图片的颜色,并将浅颜色部分变白。

Python 标准库 PIL 可以获取图片的颜色,Python2 是系统自带的,Python3 需要自己安装,我用的 Python 3.8,需要执行以下命令安装

pip install pillow

安装完成,读取图片,并获取图片的尺寸(宽度和高度)

from PIL import Image

img = Image.open('watermark_pic.png')
width, height = img.size

进行下一步之前,先简单介绍下计算机里关于颜色的知识。光学三原色是红绿蓝(RGB),也就是说它们是不可分解的三种基本颜色,其他颜色都可以通过这三种颜色混合而成,三种颜色等比例混合就是白色,没有光就是黑色。

在计算机中,可以用三个字节表示 RGB 颜色,1个字节能表示的最大数值是 255, 所以,(255, 0, 0)代表红色,(0, 255, 0)代表绿色,(0, 0, 255)代表蓝色。相应地,(255, 255, 255)代表白色,(0, 0, 0)代表黑色。从(0, 0, 0) ~ (255, 255, 255) 之间的任意组合都可以代表一个不同的颜色。

接下来我们可以通过下面代码读取图片的 RGB

for i in range(width):
for j in range(height):
pos = (i, j)
print(img.getpixel(pos)[:3])

图片每个位置颜色由四元组表示,前三位分别是 RGB,第四位是 Alpha 通道,我们不需要关心。

有了 RGB ,我们就可以对其修改。

从图中可以发现,水印的 RGB 是 #d9d9d9,这里是用十六进制表示的,其实就是(217, 217, 217)

这三个颜色值都越靠近 255,颜色就越淡,当它们都变成 255,也就成了白色。所以只要 RGB 都大于 217 的位置,我们都可以给它填成白色。即:RGB 三位数之和大于等于 651。

if sum(img.getpixel(pos)[:3]) >= 651:
img.putpixel(pos, (255, 255, 255))

完整代码如下:

from PIL import Image

img = Image.open('watermark_pic.png')
width, height = img.size for i in range(width):
for j in range(height):
pos = (i, j)
if sum(img.getpixel(pos)[:3]) >= 651:
img.putpixel(pos, (255, 255, 255)) img.save('watermark_removed_pic.png')

有了上面的基础,去除 PDF 的水印就简单了,思路是将每页 PDF 转成图片,然后修改水印的 RGB,最后输出图片即可。

安装 pymupdf 库,用来来操作 PDF

pip install pymupdf

读取 PDF,并转图片

import fitz

doc = fitz.open("数据结构和算法手册@公众号渡码.pdf")

for page in doc:
pix = page.get_pixmap()

该 PDF 共 480 页,所以需要遍历每一页,并获取每一页对应的图片pixpix对象类似于我们上面看到的img对象,可以读取、修改它的 RGB。

page.get_pixmap() 这个操作是不可逆的,即能够实现从 PDF 到图片的转换,但修改图片 RGB 后无法应用到 PDF 上,只能输出为图片。

修改水印 RGB 跟刚才一样,区别是这里的 RGB 是一个三元组,没有 Alpha 通道,代码如下:

from itertools import product

for pos in product(range(pix.width), range(pix.height)):
if sum(pix.pixel(pos[0], pos[1])) >= 651:
pix.set_pixel(pos[0], pos[1], (255, 255, 255))

完整代码如下:

from itertools import product
import fitz doc = fitz.open("数据结构和算法手册@公众号渡码.pdf") page_no = 0
for page in doc:
pix = page.get_pixmap() for pos in product(range(pix.width), range(pix.height)):
if sum(pix.pixel(pos[0], pos[1])) >= 651:
pix.set_pixel(pos[0], pos[1], (255, 255, 255)) pix.pil_save(f"pdf_pics/page_{page_no}.png", dpi=(30000, 30000)) print(f'第 {page_no} 页去除完成')
page_no += 1

这种方案是有缺点的,第一,输出并非 PDF 格式;第二,输出的图片比较模糊,后续还有待优化,最好是能直接修改 PDF。

完整代码回复关键词 gp,找great-programmer/python/python项目/去除水印目录。

PDF 源文件在great-programmer/数据结构与算法/ 目录。

后续继续分享 Python 基础以及使用工具,欢迎关注。

用Python去除PDF水印的更多相关文章

  1. C#实现多个PDF合并及去除文字水印功能

    实现pdf合并就是使用Spire.Pdf.dll类库的方法,但是注意需要同时引用Spire.Pdf.dll和Spire.License.dll两个类库,且两个类库的版本要一致 String[] fil ...

  2. python 利用opencv去除图片水印

    python 去除水印"人工"智能去除水印 这两天公司来了一个新的需求--去除水印,对于我一个从未接触过的这种事情的人来说,当时我是蒙的.不过首先我就去搜索了一下是否有该种合适的功 ...

  3. Python处理PDF和Word文档常用的方法

    Python处理PDF和Word文档的模块是PyPDF2,使用之前需要先导入. 打开一个PDF文档的操作顺序是:用open()函数打开文件并用一个变量来接收,然后把变量给传递给PdfFileReade ...

  4. Python绘制PDF文件~超简单的小程序

    Python绘制PDF文件 项目简介 这次项目很简单,本次项目课,代码不超过40行,主要是使用 urllib和reportlab模块,来生成一个pdf文件. reportlab官方文档 http:// ...

  5. python制作pdf电子书

    python制作pdf电子书 准备 制作电子书使用的是python的pdfkit这个库,pdfkit是 wkhtmltopdf 的Python封装包,因此在安装这个之前要安装wkhtmltopdf 安 ...

  6. Python 去除列表中重复的元素

    Python 去除列表中重复的元素 来自比较容易记忆的是用内置的set l1 = ['b','c','d','b','c','a','a'] l2 = list(set(l1)) print l2 还 ...

  7. python去除停用词(结巴分词下)

    python 去除停用词  结巴分词 import jieba #stopwords = {}.fromkeys([ line.rstrip() for line in open('stopword. ...

  8. Python 去除字符串中的空行

    Python 去除字符串中的空行 mystr = 'adfa\n\n\ndsfsf' print("".join([s for s in mystr.splitlines(True ...

  9. python去除列表中重复元素的方法

    列表中元素位置的索引用的是L.index 本文实例讲述了Python去除列表中重复元素的方法.分享给大家供大家参考.具体如下: 比较容易记忆的是用内置的set 1 2 3 l1 = ['b','c', ...

随机推荐

  1. php图片处理库

    <?php namespace app\common\library; /** * include 'imagick.class.php'; $image = new lib_image_ima ...

  2. 使用Git上传项目到GitHub仓库

    GitHub账号注册很长时间了,但是没怎么上传过东西.今天学习如何利用Git工具将代码上传到GitHub,了解了一些常用命令 $ git config --global user.name " ...

  3. 基于React和GraphQL的黛梦设计与实现

    写在前面 这是笔者在中秋无聊写着玩的,假期闲暇之余憋出来的帖子.麻雀虽小,但五脏俱全,涉及到的方方面面还是蛮全的.所以就设计了一个黛梦(demo)------ 打通了GraphQL的接口与前端交互的流 ...

  4. PHP中的MySQLi扩展学习(五)MySQLI_STMT对象操作

    就像 PDO 中的 PDO_Statment 对象一样,MySQLI_STMT 对象也是一个预处理语句所形成的对象,专门用来操作 MySQLi 所生成的预处理语句的.其实操作方式之类也都比较相似,不外 ...

  5. 使用 FIO 对 Kubernetes 持久卷进行 Benchmark:读/写(IOPS)、带宽(MB/s)和延迟

    工具 Dbench https://github.com/leeliu/dbench 用法 编辑 dbench.yaml 文件中的 storageClassName 以匹配你自己的 Storage C ...

  6. 谷歌浏览器chrome安装插件报"程序包无效: CRX_HEADER_INVALID"错误

    今天参加需求评审,看到原来可以谷歌浏览器查看Axure原型文件,真是只有想不到,没有做不到(自己孤陋寡闻了,第一次接触Axure). 需求评审后,我百度"如何使用谷歌浏览器查看Axure原型 ...

  7. redis的持久化 与事务管理

    1. redis的持久化 Redis的持久化主要分为两部分:RDB(Redis DataBase), AOF(Append Only File) 2. 什么是redis 的持久化        在指定 ...

  8. django 模版-标签-视图-csrf-token-模版继承-HTML过滤器

    """ ******模版****** --定义模版-- **变量** 视图传递给模版的数据 注意1:要遵守标识符规则 语法:{{var(即变量)}} 如果使用的变量不存在 ...

  9. PyCharm中文下载与安装教程【2021年更新】

    第一章:下载与安装 1.1   [版本介绍]多个版本的介绍与选择 Jetbrain 公司是一家专业的 IDE 生产商,只要是市面上主流的编程语言,Jetbrain 都有相应的产品. 比如:Python ...

  10. Jmeter压测学习1—第一个项目:登录

    我用的是我们公司的测试环境练习的 网址:http://****:9000/login.html  账号是admin 密码:123456 一.打开Jmeter 找到安装目录:bin->Jmeter ...