目录
前言
习惯用WPS的我发现,纯图PDF文件无法去除水印,所以我就用Python来去除PDF指定区域内的水印,主要就是纯色水印的处理,如果大家有什么更好的建议,请多多分享!
对比图(水印去除前后)
一、原理
- 将PDF拆成若干张图片,置于pic文件夹,并规律命名;
- 由于水印处在每张图片的相同位置,所以为了简化算法,我们可以只处理指定区域的像素;
- 对指定区域像素作判断,若是水印,则将其设为白色(255,255,255);
- 将修改后的图片输出到res文件夹内;
- 利用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'
3. 执行第二步代码
首先点击水印的左上方和用下方位置,得到水印部分的像素点位置。鼠标点击图片后,窗口会打印出(宽,高),按“q”退出。
修改变量
width_min = 143
height_min = 776
width_max = 867
height_max = 862
然后使用windows自带的画图软件,得到水印部分的颜色(像素值)。
- 因为这里我的水印是灰色的,所以RGB三色值相等,故阈值判断使用了相同变量;
- 因为我的文档正文并没有灰色的有用信息,所以我可以任意设置阈值上限,设为了255,设小了可能会有一些水印边缘残留。
修改变量
pixel_min = 150
pixel_max = 255
4. 执行第三步代码
5. 图片转PDF
得到去除水印的图片后,用WPS批量将其合成一个PDF文件(这里可能会有几张顺序不太对,不知道是什么原因,所以需要手动拖拽一下,将p1和p2拖到前面)。
参考博客: https://blog.csdn.net/qq_41251963/article/details/115306741
参考博客: https://blog.csdn.net/Cocktail_py/article/details/103004586
总结
这是我第一次写博客,感想呢就是像刚写完本科期间专业课的实验报告,看到这些规范的排版,特别有成就感,哈哈哈。
起初做这个小项目的目的是为了给女朋友去除她复习资料的水印的,因为她那个PDF文件全是图片,无法使用内部功能直接去水印,索性我就想用最近学习的Python来做这个事情,也算是第一次真正地拿来处理实际问题了。
做完这个项目之后,我才有了写博客的念头,我就是希望能够用编程来解决实际问题,记录下我能够用编程来做什么。也不知道以后多久能更一次,总之呢,只要是有实际用处的项目,无论难易程度如何,我肯定会努力去研究,如果研究明白了,我就会分享给大伙。
最近在备战考研,这一篇文章也算是个小插曲啦,有机会的话可以每天晚上研究一会,算作学习之后的放松时间。
以后研究方向应该会致力于图像处理相关的应用,属于目前自己比较感兴趣的方向吧。
最后,祝自己考研加油!!!