PDF大文件批量去除水印,又一个省心小妙招

news2024/11/26 8:29:19

PDF大文件批量去除水印,又一个省心小妙招

适用场景:本教程适合批量去除文件量较大的PDF文档内的图片水印。

使用软件:Python
需安装第三方库:PILfitzpymupdf

pip install PIL
pip install fitz
pip install pymupdf

不说废话,先把代码贴在前面。

from PIL import Image
import fitz
import os

def replace_color(img_path):
    new_color = (255, 255, 255, 255)

    for filename in os.listdir(img_path):
        image = Image.open(os.path.join(img_path, filename))
        new_pixels = [new_color if pixel == (220,220,220) else pixel for pixel in image.getdata()]

        new_image = Image.new(image.mode, image.size)
        new_image.putdata(new_pixels)
        new_image.save(os.path.join(img_path, filename))

def convert_pdf_to_images(img_path,doc):
    for i, page in enumerate(doc):
        pix = page.getPixmap(matrix=fitz.Matrix(2, 2))
        img_output_path = os.path.join(img_path, f"{i+1}.jpg")
        pix.writePNG(img_output_path)

def creat_file(img_path):
    if not os.path.exists(img_path):
        os.makedirs(img_path)
    else:
        for root, dirs, files in os.walk(img_path, topdown=False):
            for name in files:
                os.remove(os.path.join(root, name))
            for name in dirs:
                os.rmdir(os.path.join(root, name))

def convert_images_to_pdf(img_path, output_path):
    image_list = []
    for filename in sorted(os.listdir(img_path), key=lambda x: int(x.split('.')[0])):
        image_list.append(Image.open(os.path.join(img_path, filename)))
    image_list[0].save(output_path, save_all=True, append_images=image_list[1:])

def delete_watermark(file_path):
    folder_path = os.path.dirname(file_path)
    file_name = os.path.basename(file_path)
    output_path = os.path.join(folder_path, 'new_'+file_name)
    img_path = os.path.join(folder_path, f"img_{os.path.splitext(file_name)[0]}")

    creat_file(img_path)

    convert_pdf_to_images(img_path, doc=fitz.open(file_path))

    replace_color(img_path)

    image_list = [Image.open(os.path.join(img_path, filename)) for filename in sorted(os.listdir(img_path), key=lambda x: int(x.split('.')[0]))]

    image_list[0].save(output_path, save_all=True, append_images=image_list[1:])
    convert_images_to_pdf(img_path, output_path)

if __name__ == "__main__":
    delete_watermark('E:\...\example.pdf')

导入

在阅读过程中如果遇到一些带有水印的资料是比较烦心的,如下图所示,水印以及类似的内容会影响我们的阅读体验,而市面上去水印的功能有多要收费且很不方便,那么,如何通过Python来对这类图片水印进行去除呢?
在这里插入图片描述

为了不影响阅读体验,水印一般都是由灰色或红色等与正文内容明显不同的颜色构成的。因此,要去除此类水印只需要判断出它是哪种颜色,然后将此颜色替换为背景色即可。

以上面图片中的水印为例,我们通过对水印部分进行取色可以看到,水印的 RGB 值为 (128, 130, 133),背景色为白色( RGB为 (255, 255, 255) ),那么我们只需要将 RGB 值为 (128, 130, 133) 的像素值替换为 (255, 255, 255) 即可实现图像水印的去除。

博主使用的取色工具为 Snipaste,也可以用 PS 等其它工具对水印取色。

在这里插入图片描述

首先需要将 PDF 中的一页信息提取出来,我们使用的是 fitz 库。

# 将 PDF 文件分解为图片
def convert_pdf_to_images(img_path,doc)
    for i, page in enumerate(doc):
        pix = page.getPixmap(matrix=fitz.Matrix(2, 2))
        img_output_path = os.path.join(img_path, f"{i+1}.jpg")
        pix.writePNG(img_output_path)

然后再对图片中的特定颜色进行替换

def replace_color(pixel, old_color, new_color):
    if pixel in old_color:
        return new_color
    else:
        return pixel

old_color = (128, 130, 133)
new_color = (255, 255, 255) 

# 遍历输入文件夹中的所有.jpg文件并进行颜色替换
for filename in os.listdir(input_folder):
    if filename.endswith('.jpg') or filename.endswith('.png'):
        # 打开图片并获取像素数据
        image = Image.open(os.path.join(input_folder, filename))
        pixels = list(image.getdata())
        # 遍历像素数据并进行颜色替换
        new_pixels = [replace_color(pixel, old_color, new_color) for pixel in pixels]

        # 将修改后的像素数据保存到新文件夹中
        new_image = Image.new(image.mode, image.size)
        new_image.putdata(new_pixels)
        new_image.save(os.path.join(output_folder, filename))

最后再将图片拼接起来则得到去水印后的 PDF

def convert_images_to_pdf(img_path, output_path):
    image_list = []
    for filename in sorted(os.listdir(img_path), key=lambda x: int(x.split('.')[0])):
        image_list.append(Image.open(os.path.join(img_path, filename)))
    image_list[0].save(output_path, save_all=True, append_images=image_list[1:])

将以上三个步骤合并,即可得到我们的最终代码

from PIL import Image
import fitz
import os

def replace_color(img_path):
    new_color = (255, 255, 255, 255)

    for filename in os.listdir(img_path):
        image = Image.open(os.path.join(img_path, filename))
        new_pixels = [new_color if pixel == (220,220,220) else pixel for pixel in image.getdata()]

        new_image = Image.new(image.mode, image.size)
        new_image.putdata(new_pixels)
        new_image.save(os.path.join(img_path, filename))

def convert_pdf_to_images(img_path,doc):
    for i, page in enumerate(doc):
        pix = page.getPixmap(matrix=fitz.Matrix(2, 2))
        img_output_path = os.path.join(img_path, f"{i+1}.jpg")
        pix.writePNG(img_output_path)

def creat_file(img_path):
    if not os.path.exists(img_path):
        os.makedirs(img_path)
    else:
        for root, dirs, files in os.walk(img_path, topdown=False):
            for name in files:
                os.remove(os.path.join(root, name))
            for name in dirs:
                os.rmdir(os.path.join(root, name))

def convert_images_to_pdf(img_path, output_path):
    image_list = []
    for filename in sorted(os.listdir(img_path), key=lambda x: int(x.split('.')[0])):
        image_list.append(Image.open(os.path.join(img_path, filename)))
    image_list[0].save(output_path, save_all=True, append_images=image_list[1:])

def delete_watermark(file_path):
    folder_path = os.path.dirname(file_path)
    file_name = os.path.basename(file_path)
    output_path = os.path.join(folder_path, 'new_'+file_name)
    img_path = os.path.join(folder_path, f"img_{os.path.splitext(file_name)[0]}")

    creat_file(img_path)

    convert_pdf_to_images(img_path, doc=fitz.open(file_path))

    replace_color(img_path)

    image_list = [Image.open(os.path.join(img_path, filename)) for filename in sorted(os.listdir(img_path), key=lambda x: int(x.split('.')[0]))]

    image_list[0].save(output_path, save_all=True, append_images=image_list[1:])
    convert_images_to_pdf(img_path, output_path)

if __name__ == "__main__":
    delete_watermark('E:\...\example.pdf')

只需要对水印和背景进行取色,然后更改相应代码即可实现全自动 Python 去水印功能。

由于水印颜色并不总是某一个RGB值,而是一个范围,所以也可以使用 218<pixel[0]<244 and 218<pixel[1]<244 and 218<pixel[2]<244: 替换 pixel == (220,220,220)

上述程序在运行过程中会根据文件名,产生一个"img_[文件名]"文件夹用于存放图片,以及产生一个去除水印后的"new_[文件名].pdf"文件。

在这里插入图片描述

若不需要查看单张图片的效果,也可以直接运行如下代码,在等待一段时间后会直接生成去除水印后的 PDF。

import fitz

with fitz.open('example.pdf') as doc:
    for page in doc:
        pix = page.getPixmap(matrix=fitz.Matrix(2, 2))
        pix = pix.applyFunction(lambda r,g,b: (255, 255, 255) if (r,g,b) == (220, 220, 220) else (r,g,b))
        new_page = fitz.new_page(width=pix.width, height=pix.height)
        new_page.insert_image(fitz.Rect(0, 0, pix.width, pix.height), pixmap=pix)

new_doc.save("new_example.pdf")

不过该方法生成的 PDF 文件会远大于原始文件,若是介意这点可继续用前一种方法。关于文件变大这点,如果有知道原因的朋友可以留下评论。

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

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

相关文章

Robot Framework+Jenkins持续集成UI自动化项目

使用Robot Framework框架可进行Web端和APP端的UI自动化测试&#xff0c;为方便定时执行&#xff0c;可将Robot Framework的自动化项目持续集成至Jenkins平台&#xff0c;具体的操作步骤如下&#xff1a; 安装Jenkins的步骤如下&#xff1a; 手把手教小白安装Jenkins_程序员馨馨…

关于对【java中的Lambda表达式】的理解与简述

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/130522535 出自【进步*于辰的博客】 坦白说&#xff0c;在我学会如何使用Lambda表达式后&#x…

机器学习笔记:高斯混合模型 GMM

1 高斯混合模型 总体分布是由K个高斯分布的组成的混合分布 1.1 一些记号 xj第j个观测数据K模型中高斯模型的数量αk 观测数据属于第k个子模型的概率 第k个子模型的高斯分布密度函数 &#xff08;也就是一个高斯分布的密度函数 第j个观测数据属于第k个子模型的概率 1.2 高斯…

Windows环境下安装Redis

下载地址&#xff1a; Releases microsoftarchive/redis GitHub Redis 支持 32 位和 64 位。这个需要根据你系统平台的实际情况选择&#xff0c;这里我们下载 Redis-x64-xxx.zip压缩包到 D 盘redis文件夹下。 网盘下载&#xff1a; 链接&#xff1a;https://pan.baidu.co…

web应用安全漏洞

注入类 数据库注入 SQL注入 结构化查询语言 (Structured Query Language)简称SQL&#xff0c;结构化查询语言是一种数 据库查询和程序设计语言&#xff0c;用于存取数据以及查询、更新和管理关系数据库系统 关系型数据库 &#xff0c;是指采用了关系模型来组织数据的数据库&…

STM32(一)准备开发环境CLion+CubeMX

本篇内容 一、CLion和STM32CubeMX基础安装二、安装OpenOCD三、安装交叉编译工具链四、配置CLion并点亮第一个LED灯五、烧录程序六、错误排查 本篇安装配置STM32的开发环境&#xff0c;使用的是稚晖君同款CLionSTM32CubeMX的开发环境 一、CLion和STM32CubeMX基础安装 软件安装只…

Java-API简析_java.lang.Integer类(基于JDK1.8)(浅析源码)

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/130730986 出自【进步*于辰的博客】 其实我的【Java-API】专栏内的博文对大家来说意义是不大的。…

Python绘制带误差棒的柱状图渐变色填充含数据标注(进阶)

往期python绘图合集: python绘制简单的折线图 python读取excel中数据并绘制多子图多组图在一张画布上 python绘制带误差棒的柱状图 python绘制多子图并单独显示 python读取excel数据并绘制多y轴图像 python绘制柱状图并美化|不同颜色填充柱子 文章目录 准备数据一、绘制图表二、…

Android RecyclerView实现吸顶动态效果,附详细效果图

文章目录 一、ItemDecoration二、实现RecyclerView吸顶效果1、实现一个简单的RecyclerView2、通过ItemDecoration画分割线3、画出每个分组的组名4、实现吸顶效果 完整demo 链接:https://download.csdn.net/download/JasonXu94/87786702 一、ItemDecoration [外链图片转存失败…

SpringDataRedis

SpringDataRedis SpringDataRedis简介RedisTemplate对Redis操作类型SpringDataRedis快速入门1、引入spring-boot-starter-data-redis依赖2、在application.properties配置Redis信息3、注入RedisTemplate并测试 SpringDataRedis的序列化方式现象分析SpringDataRedis的序列化方式…

基于RK3588的以太网PHY的问题分析

环境:RK3588为荣品电子核心板,PHY为裕太微电子YT8521; 首先上电后识别不到以太网: 1.先怀疑驱动的问题,因为本方案中直接使用的是荣品电子官方的驱动; 对比原理图及驱动。涉及到一个配置问题。 基于时钟来源的不通,驱动程序可分为四种模式,PHY的时钟和TXCLK的时钟;…

北华大学第九届程序设计竞赛 题解

5.14和队友VP一场&#xff0c;第二次VP&#xff0c;状态明显比第一次好很多&#xff0c;总共A了7题&#xff0c;基本是能做出来的都做出来了&#xff0c;最后还剩下接近2小时的时间。。。。。 A "北华"有几何 思路&#xff1a;数图片中“北华”的数量&#xff0c;直…

双平台GraalVM编译二进制程序

本文示例均采用Java11&#xff0c;GraalVM目前无法支持跨平台编译&#xff0c;比如&#xff0c;我通过Linux直接编译Windows可执行的exe&#xff0c;是不行的。 因此&#xff0c;需要掌握两种平台的GraalVM的安装、使用。 一、背景 1.1 为何GraalVM快&#xff1f; 常规Java…

永恒之塔私服 2.0包楼纳斯达克 网游的诺曼底登陆-

二战末期的诺曼底登陆&#xff0c;至今让人历历在目。盟军自此在西欧展开大规模进攻&#xff0c;加速了纳粹德国的崩溃。从某种意义上说&#xff0c;诺曼底登陆是整个二战一次生死攸关的转折点。《永恒之塔2.0&#xff1a;进军龙界》登上纳斯达克&#xff0c;也是一场激荡人心的…

基于自动编码器VAE的声音生成之音频预处理模块preprocess pipeline的实现和代码讲解

文章目录 概述Preprocessline模块实现以及代码讲解Loader模块Padder模块LogSpectrogramExtractor模块MinMaxNormaliser模块Saver模块PreprocessPipeLine模块知识补充property修饰词 总结 概述 这部分是将原来基于mnist手写数据集生成模型&#xff0c;一个用到基于FSDD音频数据…

蓝桥:前端开发笔面必刷题——Day2 数组(二)

文章目录 &#x1f4cb;前言&#x1f3af;删除有序数组中的重复项&#x1f4da;题目内容✅解答 &#x1f3af;移动零&#x1f4da;题目内容✅解答 &#x1f3af;长度最小的子数组&#x1f4da;题目内容✅解答 &#x1f3af;反转字符串数组&#x1f4da;题目内容✅解答 &#x1…

麒麟操作系统软件更新灾难连篇之二:QQ罢工

在解决了中文输入法消失的问题后&#xff0c;还没缓过气来&#xff0c;又发现QQ罢工了&#xff1a;双击电脑桌面上的QQ图标&#xff0c;没有显示QQ登录界面。 重启电脑再试&#xff0c;还是不显示QQ登录界面。 前不久腾讯正式宣布&#xff0c;QQ Linux 版 3.0 已在 QQ 官网上…

最好用的文本与文件查询软件AnyTXT Searcher与Listary简介

1. 工具简介 1.1 Listary简介 Listary是一个革命性的Windows搜索工具&#xff0c;借助 Listary软件&#xff0c;你可以快速搜索电脑文件、定位文件、执行智能命令、记录访问历史、快速切换目录、收藏常用项目等。 Listary为Windows传统低效的文件打开/保存对话框提供了便捷、…

Apache Tomcat AJP协议文件读取与包含

永远也不要忘记能够笑的坚强&#xff0c;就算受伤&#xff0c;我也从不彷徨。 0x01.漏洞情况分析 Tomcat是Apache软件基金会Jakarta 项目中的一个核心项目&#xff0c;作为目前比较流行的Web应用服务器&#xff0c;深受Java爱好者的喜爱&#xff0c;并得到了部分软件开发商的…

makefile 学习(2):C语言的编译及库文件的生成与链接

文章目录 1. 介绍2. C语言编译2.1 预处理2.2 生成汇编语言2.3 编译目标文件2.4 编译为可执行文件 3. .a静态库的编译与链接案例 4 .so 动态库的编译与链接 1. 介绍 编译C语言的相关后缀 .a 文件是一个静态库文件.c文件是c语言的源文件.h c语言的头文件.i 是预处理文件.o 目标文…