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

python一键去PDF水印,只需十行代码,超级简单...

用python制作去除 pdf 文件水印脚本

  • 前因后果
  • 去除水印原理
  • 代码剖析
      • 1、先查看PDF文档中的水印rgb值是多少
      • 2、pdf转换成图片,并去除水印
      • 3、图片转为pdf
  • 代码整合
  • 总结

前因后果

弟弟最近要考试,临时抱佛脚在网上找了一堆学习资料复习,这不刚就来找我了,说PDF上有水印,影响阅读效果,到时候考不好就怪资料不行,气的我差点当场想把他揍一顿!

算了,弟弟长大了,看在打不过他的份上,就不打他了~

稍加思索,我想起了Python不是可以去水印?说搞就搞!

去除水印原理

去除方法:

  1. 用 PyMuPDF 打开 pdf 文件,将 pdf 的每一页都转换为图片 pixmap
  2. pixmap 有它自己的RGB,只需要将 pdf 水印中的 RGB 改为(255, 255, 255),并保存图片 ;
  3. 按照生成的图片,插入到pdf文档中;

因为pfd文档无法直接去除水印,需要先将pfd文档转换成图片,在逐一对图片进行水印去除操作,最后在把图片插入到pdf文档中。

代码剖析

1、先查看PDF文档中的水印rgb值是多少

可以看到,RGB(179,179,179),因为这里要的是RGB色值总和,所以我们就认为,超过510,就认为是水印。

敲黑板

光学三原色是红绿蓝(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,第四位是 Alpha 通道

2、pdf转换成图片,并去除水印

代码示例:

from PIL import Image
from itertools import product
import fitz

# 去除pdf的水印
def remove_pdfwatermark():
    #打开源pfd文件
    pdf_file = fitz.open("源码找落落阿.pdf")

    #page_no 设置为0
    page_no = 0
    #page在pdf文件中遍历
    for page in pdf_file:
        #获取每一页对应的图片pix (pix对象类似于我们上面看到的img对象,可以读取、修改它的 RGB)
        #page.get_pixmap() 这个操作是不可逆的,即能够实现从 PDF 到图片的转换,但修改图片 RGB 后无法应用到 PDF 上,只能输出为图片
        pix = page.get_pixmap()

        #遍历图片中的宽和高,如果像素的rgb值总和大于510,就认为是水印,转换成255,255,255-->即白色
        for pos in product(range(pix.width), range(pix.height)):
            if sum(pix.pixel(pos[0], pos[1])) >= 510:
                pix.set_pixel(pos[0], pos[1], (255, 255, 255))
        #保存去掉水印的截图
        pix.pil_save(f"./{page_no}.png", dpi=(30000, 30000))
        #打印结果
        print(f'第 {page_no} 页去除完成')

        page_no += 1

if __name__ == '__main__':
    remove_pdfwatermark()

执行完成

查看生成图片:

查看图片内容

3、图片转为pdf

代码示例:

from PIL import Image
from itertools import product
import fitz

''' 图片转为pdf'''
#图片所在的文件夹
pic_dir = 'F:\123'

pdf = fitz.open()
#图片数字文件先转换成int类型进行排序
img_files = sorted(os.listdir(pic_dir), key=lambda x: int(str(x).split('.')[0]))
for img in img_files:
    print(img)
    imgdoc = fitz.open(pic_dir + '/' + img)
    #将打开后的图片转成单页pdf
    pdfbytes = imgdoc.convertToPDF()
    imgpdf = fitz.open("pdf", pdfbytes)
    #将单页pdf插入到新的pdf文档中
    pdf.insertPDF(imgpdf)
pdf.save("源码找落落阿_完成.pdf")
pdf.close()

执行代码

查看生成的pdf文档

代码整合

上面的内容都了解以后,我们就整合代码,直接运行就可以了。

from PIL import Image
from itertools import product
import fitz


# 去除pdf的水印
def remove_pdfwatermark():
    # 打开源pfd文件
    pdf_file = fitz.open("源码找落落阿.pdf")

    # page_no 设置为0
    page_no = 0
    # page在pdf文件中遍历
    for page in pdf_file:
        # 获取每一页对应的图片pix (pix对象类似于我们上面看到的img对象,可以读取、修改它的 RGB)
        # page.get_pixmap() 这个操作是不可逆的,即能够实现从 PDF 到图片的转换,但修改图片 RGB 后无法应用到 PDF 上,只能输出为图片
        pix = page.get_pixmap()

        # 遍历图片中的宽和高,如果像素的rgb值总和大于510,就认为是水印,转换成255,255,255-->即白色
        for pos in product(range(pix.width), range(pix.height)):
            if sum(pix.pixel(pos[0], pos[1])) >= 510:
                pix.set_pixel(pos[0], pos[1], (255, 255, 255))
        # 保存去掉水印的截图
        pix.pil_save(f"./{page_no}.png", dpi=(30000, 30000))
        # 打印结果
        print(f'第 {page_no} 页去除完成')

        page_no += 1


# 去除的pdf水印添加到pdf文件中
def pictopdf():
    # 水印截图所在的文件夹
    # pic_dir = input("请输入图片文件夹路径:")
    pic_dir = 'F:\123'

    pdf = fitz.open()
    # 图片数字文件先转换成int类型进行排序
    img_files = sorted(os.listdir(pic_dir), key=lambda x: int(str(x).split('.')[0]))
    for img in img_files:
        print(img)
        imgdoc = fitz.open(pic_dir + '/' + img)
        # 将打开后的图片转成单页pdf
        pdfbytes = imgdoc.convertToPDF()
        imgpdf = fitz.open("pdf", pdfbytes)
        # 将单页pdf插入到新的pdf文档中
        pdf.insertPDF(imgpdf)
    pdf.save("源码找落落阿_完成.pdf")
    pdf.close()


if __name__ == '__main__':
    remove_pdfwatermark()
    pictopdf()

兄弟们学习python,有时候不知道怎么学,从哪里开始学。掌握了基本的一些语法或者做了两个案例后,不知道下一步怎么走,不知道如何去学习更加高深的知识。
那么对于这些大兄弟们,我准备了大量的免费视频教程,PDF电子书籍,以及源代码!
直接在文末名片自取即可~








总结

需要理解的流程是:

  • pdf文档需要先转换成图片,进行水印去除;
  • 再转换成pdf ;
  • 最后插入到新的pdf文档中;

写到这里,今天的分享就差不多快结束了,咱们下次再见!

相关文章:

  • 城市消费券,拒绝恶意爬取
  • C语言第十一课(下):优化扫雷游戏
  • MySQL之优化SELECT语句
  • IPv6与VoIP——ipv6接口标识与VoIP概述
  • 性能测试_JMeter_connection timed out :connect
  • SpringCloud 相关
  • 精华推荐 | 【深入浅出RocketMQ原理及实战】「底层原理挖掘系列」透彻剖析贯穿RocketMQ的存储系统的实现原理和持久化机制
  • 基于JAVA的会议管理系统参考【数据库设计、源码、开题报告】
  • 爬虫基础知识
  • LeetCode 0525. 连续数组:哈希表 + 前缀和
  • 隐私计算 FATE - 多分类神经网络算法测试
  • 【蓝桥杯Web】第十四届蓝桥杯(Web 应用开发)模拟赛 2 期 | 精品题解
  • 【web渗透思路】敏感信息泄露(网站+用户+服务器)
  • vue.js毕业设计,基于vue.js前后端分离教室预约小程序系统设计与实现
  • 2022第8届中国大学生程序设计竞赛CCPC威海站, 签到题7题
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • 〔开发系列〕一次关于小程序开发的深度总结
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • github指令
  • HTTP中的ETag在移动客户端的应用
  • JS字符串转数字方法总结
  • NSTimer学习笔记
  • Redis学习笔记 - pipline(流水线、管道)
  • spring security oauth2 password授权模式
  • vue-cli在webpack的配置文件探究
  • 从零开始在ubuntu上搭建node开发环境
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 入门到放弃node系列之Hello Word篇
  • 使用 Xcode 的 Target 区分开发和生产环境
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • #pragma 指令
  • (1)常见O(n^2)排序算法解析
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (floyd+补集) poj 3275
  • (zhuan) 一些RL的文献(及笔记)
  • (一)UDP基本编程步骤
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .apk文件,IIS不支持下载解决
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端
  • .NET/C# 使用 SpanT 为字符串处理提升性能
  • .NET委托:一个关于C#的睡前故事
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • /etc/fstab和/etc/mtab的区别
  • [ vulhub漏洞复现篇 ] Grafana任意文件读取漏洞CVE-2021-43798
  • [ActionScript][AS3]小小笔记
  • [BZOJ 4598][Sdoi2016]模式字符串
  • [BZOJ] 2427: [HAOI2010]软件安装
  • [C/C++]数据结构 循环队列
  • [CSS] - 修正IE6不支持position:fixed的bug
  • [leetcode] Longest Palindromic Substring