我目前正在使用python去除PDF文件中的水印。例如,我有一个这样的文件:
页面中央的绿色形状是水印。我认为它不是以文本形式存储在PDF中,因为我无法通过简单地使用Edge浏览器(可以读取PDF文件)搜索来找到该文本。 另外,我无法按图像找到水印。我使用 PyMuPDF 从 PDF 中提取了所有图像,并且没有找到水印(应该出现在每个页面上)。
我用来提取的代码是这样的:
document = fitz.open(self.input)
for each_page in document:
image_list = each_page.getImageList()
for image_info in image_list:
pix = fitz.Pixmap(document, image_info[0])
png = pix.tobytes() # return picture in png format
if png == watermark_image:
document._deleteObject(image_info[0])
document.save(out_filename)
那么如何使用Python的库找到并删除水印呢?水印如何存储在 PDF 中?
除了 PyMuPDF 之外,还有其他“神奇”库可以完成此任务吗?
对于任何对详细信息感兴趣的人,请参阅此处提供的解决方案。 删除此文件中使用的水印类型可与 PyMuPDF 的低级代码接口一起使用。没有直接的、专门的高级 API 来执行此操作。
我尝试了以下代码,该代码是根据 pymupdf github 讨论查找并删除 PDF 文件中的水印中的代码进行了一些修改。它在当前的 pymupdf 版本上工作正常。
pip install PyMuPDF
import pymupdf
def process_page(page : pymupdf.Page):
"""Process one page."""
# doc = page.parent # the page's owning document
# page.clean_contents() # clean page painting syntax
xref = page.get_contents()[0] # get xref of resulting /Contents
changed = 0 # this will be returned
# read sanitized contents, splitted by line breaks
cont_lines = page.read_contents().splitlines()
print(len(cont_lines))
# print(cont_lines)
for i in range(len(cont_lines)): # iterate over the lines
line = cont_lines[i]
# print(line)
if not (line.startswith(b"/Artifact") and b"/Watermark" in line):
continue # this was not for us
# line number i starts the definition, j ends it:
print(line)
j = cont_lines.index(b"EMC", i)
for k in range(i, j):
# look for image / xobject invocations in this line range
do_line = cont_lines[k]
if do_line.endswith(b"Do"): # this invokes an image / xobject
cont_lines[k] = b"" # remove / empty this line
changed += 1
if changed > 0: # if we did anything, write back modified /Contents
doc.update_stream(xref, b"\n".join(cont_lines))
return changed
fpath = 'your_pdf_file_path/file_name.pdf'
doc = pymupdf.open(fpath)
changed = 0 # indicates successful removals
for page in doc:
changed += process_page(page) # increase number of changes
if changed > 0:
x = "s" if doc.page_count > 1 else ""
print(f"{changed} watermarks have been removed on {doc.page_count} page{x}.")
doc.ez_save(doc.name.replace(".pdf", "-nowm.pdf"))
else:
print("Nothing to change")