remove water mark PROOF in vista generaed pdf using colab after upload input.pdf as orginal in content folder of colab
# ============================================================
# REMOVE "PROOF" WATERMARK FROM THIS TYPE OF PDF
# ============================================================
#
# Input : /content/input.pdf
# Output: /content/out.pdf
#
# The watermark is stored inside a nested Form XObject.
# We remove ONLY the text drawing operation (BT ... ET).
# The original page/image is preserved.
# ============================================================
!pip install PyMuPDF -q
import fitz
import re
import os
from google.colab import files
INPUT = "/content/input.pdf"
OUTPUT = "/content/out.pdf"
doc = fitz.open(INPUT)
print("Pages:", len(doc))
removed = 0
for page_no, page in enumerate(doc, start=1):
print(f"\nProcessing page {page_no}...")
# --------------------------------------------------------
# Find all Form XObjects recursively
# --------------------------------------------------------
def process_xobject(xref, level=0):
global removed
try:
obj = doc.xref_object(xref)
# Check whether this is a Form XObject
if "/Subtype /Form" not in obj:
return
# Read its content stream
stream = doc.xref_stream(xref)
if not stream:
return
# ------------------------------------------------
# Check whether this Form contains text
# ------------------------------------------------
if b"BT" in stream and b"ET" in stream:
old_stream = stream
# ------------------------------------------------
# Remove the watermark text section.
#
# In your PDF the relevant section is:
#
# q
# /GS0 gs
# ...
# BT
# /F1 ...
# ...
# Tj
# ...
# ET
# Q
#
# Keep the image and remove this text layer.
# ------------------------------------------------
pattern = (
rb'q\s*'
rb'/GS0\s+gs'
rb'.*?'
rb'\bBT\b'
rb'.*?'
rb'\bET\b'
rb'\s*Q'
)
new_stream, count = re.subn(
pattern,
b'',
stream,
flags=re.DOTALL
)
if count > 0:
doc.update_stream(xref, new_stream)
removed += count
print(
f" Removed watermark text from "
f"XObject {xref}"
)
return
# ------------------------------------------------
# Find nested XObjects
# ------------------------------------------------
# Look at /Resources associated with this object
m = re.search(
rb'/Resources\s+(\d+)\s+0\s+R',
obj.encode("latin1")
)
if not m:
return
resources_xref = int(m.group(1))
resources_obj = doc.xref_object(resources_xref)
# Find XObject references
refs = re.findall(
rb'/\w+\s+(\d+)\s+0\s+R',
resources_obj.encode("latin1")
)
for ref in refs:
child_xref = int(ref)
if child_xref != xref:
process_xobject(
child_xref,
level + 1
)
except Exception as e:
print(
f" XObject {xref} skipped: {e}"
)
# --------------------------------------------------------
# Start with page content XObjects
# --------------------------------------------------------
resources = page.get_text("rawdict")
# Get page object
page_obj = doc.xref_object(page.xref)
# Find page Resources
match = re.search(
r'/Resources\s+(\d+)\s+0\s+R',
page_obj
)
if match:
resources_xref = int(match.group(1))
resources_obj = doc.xref_object(resources_xref)
# Find XObjects
xrefs = re.findall(
r'/\w+\s+(\d+)\s+0\s+R',
resources_obj
)
for xref_str in xrefs:
process_xobject(int(xref_str))
# ============================================================
# Save
# ============================================================
doc.save(
OUTPUT,
garbage=4,
deflate=True
)
doc.close()
print("\n==========================================")
print("COMPLETED")
print("==========================================")
print("Watermark sections removed:", removed)
print("Output file:", OUTPUT)
print("File exists:", os.path.exists(OUTPUT))
print("==========================================")
# Download
files.download(OUTPUT)