Python项目实践(一)去除PDF指定区域内的水印

本文介绍了一种使用Python去除PDF纯色水印的方法,通过将PDF拆分成图片,处理指定区域像素,再合成为PDF。主要涉及图像处理库如OpenCV和fitz,以及代码实现步骤,包括获取水印区域像素位置和去除水印。适合对PDF处理和图像处理感兴趣的读者。
摘要由CSDN通过智能技术生成


前言

习惯用WPS的我发现,纯图PDF文件无法去除水印,所以我就用Python来去除PDF指定区域内的水印,主要就是纯色水印的处理,如果大家有什么更好的建议,请多多分享!

对比图(水印去除前后)

原图
效果图

一、原理

  1. 将PDF拆成若干张图片,置于pic文件夹,并规律命名;
  2. 由于水印处在每张图片的相同位置,所以为了简化算法,我们可以只处理指定区域的像素;
  3. 对指定区域像素作判断,若是水印,则将其设为白色(255,255,255);
  4. 将修改后的图片输出到res文件夹内;
  5. 利用WPS将多个图片合成一个PDF。

二、代码实现

import fitz
import os
import cv2 as cv
import numpy as np

def func(doc):
    '''
    将pdf中所有图片写入文件夹
    '''
    for i in range(len(doc)):
        imglist = doc.getPageImageList(i)
        for j, img in enumerate(imglist):
            xref = img[0]
            pix = fitz.Pixmap(doc, xref)   # make pixmap from image
            if pix.n - pix.alpha < 4:      # can be saved as PNG
                pix.writePNG("./pic/p%s.png" % (i + 1))
            else:                          # CMYK: must convert first
                pix0 = fitz.Pixmap(fitz.csRGB, pix)
                pix0.writePNG("./pic/p%s.png" % (i + 1))
                pix0 = None                # free Pixmap resources
            pix = None                     # free Pixmap resources
    print('PDF拆分完毕')


def console_location(path):
    """
    控制台输出区域像素的位置
    """
    img = cv.imread(path)

    def on_mouse(event, x, y, flags, param):
        if event == cv.EVENT_LBUTTONDOWN:
            print(x, y)  # 宽*高
    # 构建窗口
    # 回调绑定窗口
    cv.namedWindow("img", cv.WINDOW_NORMAL)
    cv.setMouseCallback("img", on_mouse, 0)
    cv.imshow("img", img)
    # 键盘输入'q'退出
    if cv.waitKey() == ord("q"):
        cv.destroyAllWindows()


def remove(w_min, h_min, w_max, h_max, pixel_min, pixel_max):
    """
    去除水印
    """
    list_file = os.listdir('./pic')
    for filename in list_file:
        print('正在处理图片:' + filename)
        img = cv.imread('./pic/' + filename)
        for h in range(height_min, height_max):
            for w in range(width_min, width_max):
                # 像素读取顺序是BGR
                (b, g, r) = img[h, w]
                if (pixel_min < r < pixel_max and pixel_min < g < pixel_max and pixel_min < b < pixel_max):
                    img[h, w] = [255, 255, 255]
        # 保存图片
        cv.imwrite("./res/" + filename, img)
    print('水印去除完毕')


if __name__ == "__main__":
    # 注意:需要自行创建好pic和res的空文件夹
    # PDF和其中一个样例图片的路径
    pdf_path = 'file.pdf'
    pic_path = './pic/p1.png'
    # 需要滤除的区域像素值
    pixel_min = 150
    pixel_max = 255
    # 需要滤除的区域像素位置
    width_min = 149
    height_min = 770
    width_max = 850
    height_max = 862

    # 第一步:将pdf中所有图片写入文件夹
    # func(doc=fitz.open(pdf_path))
    # 第二步:获得水印区域像素的位置
    # console_location(pic_path)
    # 第三步:去除文件夹内所有图片指定范围的灰色区域
    remove(width_min, height_min, width_max, height_max, pixel_min, pixel_max)

三、使用教程

1. 文件夹目录(pic和res文件夹需提前创建好)

起始文件夹目录

2. 执行第一步代码(注释掉其他代码,以下同理)

修改变量

    pdf_path = 'file.pdf'

拆分PDF为图片

3. 执行第二步代码

首先点击水印的左上方和用下方位置,得到水印部分的像素点位置。鼠标点击图片后,窗口会打印出(宽,高),按“q”退出。
获得像素位置信息
修改变量

    width_min = 143
    height_min = 776
    width_max = 867
    height_max = 862

然后使用windows自带的画图软件,得到水印部分的颜色(像素值)。

  1. 因为这里我的水印是灰色的,所以RGB三色值相等,故阈值判断使用了相同变量;
  2. 因为我的文档正文并没有灰色的有用信息,所以我可以任意设置阈值上限,设为了255,设小了可能会有一些水印边缘残留。

获得像素值RGB
修改变量

    pixel_min = 150
    pixel_max = 255

4. 执行第三步代码

结果图

5. 图片转PDF

得到去除水印的图片后,用WPS批量将其合成一个PDF文件(这里可能会有几张顺序不太对,不知道是什么原因,所以需要手动拖拽一下,将p1和p2拖到前面)。
WPS功能

参考博客: https://blog.csdn.net/qq_41251963/article/details/115306741
参考博客: https://blog.csdn.net/Cocktail_py/article/details/103004586


总结

这是我第一次写博客,感想呢就是像刚写完本科期间专业课的实验报告,看到这些规范的排版,特别有成就感,哈哈哈。
起初做这个小项目的目的是为了给女朋友去除她复习资料的水印的,因为她那个PDF文件全是图片,无法使用内部功能直接去水印,索性我就想用最近学习的Python来做这个事情,也算是第一次真正地拿来处理实际问题了。
做完这个项目之后,我才有了写博客的念头,我就是希望能够用编程来解决实际问题,记录下我能够用编程来做什么。也不知道以后多久能更一次,总之呢,只要是有实际用处的项目,无论难易程度如何,我肯定会努力去研究,如果研究明白了,我就会分享给大伙。
最近在备战考研,这一篇文章也算是个小插曲啦,有机会的话可以每天晚上研究一会,算作学习之后的放松时间。
以后研究方向应该会致力于图像处理相关的应用,属于目前自己比较感兴趣的方向吧。

最后,祝自己考研加油!!!

回答: 要使用Python去除PDF中的水印,可以使用PyPDF4库来实现。首先,你需要导入PyPDF4库并创建一个PdfFileWriter对象来存储处理后的PDF文件。然后,使用PdfFileReader对象打开带有水印PDF文件。接下来,你可以使用getPage()方法获取PDF的页面,并使用\['/Resources'\]\['/XObject'\]来访问页面的结构。通常情况下,水印元素都在\['/Resources'\]\['/XObject'\]中。你可以通过删除特定水印元素来去除水印。最后,将处理后的页面添加到PdfFileWriter对象中,并将结果写入新的PDF文件中。下面是一个示例代码: ```python from PyPDF4 import PdfFileReader, PdfFileWriter output = PdfFileWriter() pdf = PdfFileReader("C:/Users/13283/Desktop/hahaha/output/Drawing1.pdf", 'rb') pdf1 = pdf.getPage(0) pdf1\['/Resources'\]\['/XObject'\]\['/Trn3dK9'\].clear() output.addPage(pdf1) with open("C:/Users/13283/Desktop/hahaha/output/out.pdf", 'wb') as ouf: output.write(ouf) ``` 在这个示例代码中,"C:/Users/13283/Desktop/hahaha/output/Drawing1.pdf"是带有水印PDF文件路径。pdf1=pdf.getPage(0)表示获取第一页,如果有多页的话,可以使用循环来遍历每一页。一般来说,水印的元素大多数都在pdf1\['/Resources'\]\['/XObject'\]中。\['/Trn3dK9'\]是表示要删除水印元素。通过删除该元素,水印就会消失。最后,将处理后的页面添加到PdfFileWriter对象中,并将结果写入新的PDF文件中。 #### 引用[.reference_title] - *1* *2* [用PythonPDF水印(终极版)原则上所有水印都可去除Pdftron)](https://blog.csdn.net/m0_53956136/article/details/127633298)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值