import os
from pathlib import Path
from pypdf import PdfReader, PdfWriter
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter, A4
from reportlab.lib.colors import Color
import io
# ============================================================
# STEP 1: Create Text Watermark as PDF (in memory)
# ============================================================
def create_text_watermark(text, page_width, page_height,
font_size=50, opacity=0.15,
rotation=45, color=(0.5, 0.5, 0.5)):
"""
Generate a transparent diagonal text watermark
and return it as a PDF bytes object.
"""
packet = io.BytesIO()
c = canvas.Canvas(packet, pagesize=(page_width, page_height))
# Set transparency
c.setFillColor(Color(color[0], color[1], color[2], alpha=opacity))
c.setFont("Helvetica-Bold", font_size)
# Move to center of page and rotate
c.translate(page_width / 2, page_height / 2)
c.rotate(rotation)
# Draw watermark text centered
c.drawCentredString(0, 0, text)
c.save()
packet.seek(0)
return packet
# ============================================================
# STEP 2: Create Image Watermark as PDF (in memory)
# ============================================================
def create_image_watermark(image_path, page_width, page_height,
opacity=0.2, scale=0.4):
"""
Place an image watermark centered on the page.
"""
packet = io.BytesIO()
c = canvas.Canvas(packet, pagesize=(page_width, page_height))
img_width = page_width * scale
img_height = page_height * scale
x = (page_width - img_width) / 2
y = (page_height - img_height) / 2
c.setFillAlpha(opacity)
c.drawImage(image_path, x, y, width=img_width, height=img_height,
mask='auto', preserveAspectRatio=True)
c.save()
packet.seek(0)
return packet
# ============================================================
# STEP 3: Apply Watermark to Each Page
# ============================================================
def apply_watermark(input_pdf, output_pdf, watermark_packet_func,
page_range=None):
"""
Merge watermark onto each page of the input PDF.
page_range: tuple (start, end) 1-indexed inclusive, or None for all pages
"""
reader = PdfReader(input_pdf)
writer = PdfWriter()
total_pages = len(reader.pages)
print(f"\n Total pages in PDF: {total_pages}")
# Determine page range
if page_range:
start = max(0, page_range[0] - 1)
end = min(total_pages, page_range[1])
else:
start = 0
end = total_pages
for i, page in enumerate(reader.pages):
if start <= i < end:
# Get actual page dimensions
media_box = page.mediabox
page_w = float(media_box.width)
page_h = float(media_box.height)
# Create fresh watermark for this page size
wm_packet = watermark_packet_func(page_w, page_h)
wm_reader = PdfReader(wm_packet)
watermark_page = wm_reader.pages[0]
# Merge watermark onto page
page.merge_page(watermark_page)
writer.add_page(page)
with open(output_pdf, "wb") as f:
writer.write(f)
print(f" Watermarked PDF saved: {output_pdf}")
# ============================================================
# STEP 4: Batch Watermark Multiple PDFs
# ============================================================
def batch_watermark(folder_path, watermark_func, suffix="_watermarked"):
folder = Path(folder_path)
pdf_files = list(folder.glob("*.pdf"))
if not pdf_files:
print(" No PDF files found in folder.")
return
print(f"\n Found {len(pdf_files)} PDF(s) — processing...")
for pdf in pdf_files:
output_name = pdf.stem + suffix + ".pdf"
output_path = pdf.parent / output_name
try:
apply_watermark(str(pdf), str(output_path), watermark_func)
except Exception as e:
print(f" ⚠ Error processing {pdf.name}: {e}")
# ============================================================
# HELPER: Get Page Range Input
# ============================================================
def get_page_range(total_hint="all"):
choice = input(f"\nApply watermark to all pages or specific range? (all/range) [{total_hint}]: ").strip().lower()
if choice == "range":
start = int(input(" Start page (1-indexed): ").strip())
end = int(input(" End page: ").strip())
return (start, end)
return None
# ============================================================
# MAIN MENU
# ============================================================
def main():
print("\n" + "="*55)
print(" PDF WATERMARK ADDER")
print("="*55)
print("\nMode:")
print(" 1. Add TEXT watermark to single PDF")
print(" 2. Add IMAGE watermark to single PDF")
print(" 3. Batch TEXT watermark (entire folder)")
mode = input("\nEnter choice (1/2/3): ").strip()
# ---- Single PDF Modes ----
if mode in ["1", "2"]:
input_pdf = input("\nEnter input PDF path: ").strip()
if not os.path.isfile(input_pdf):
print(" Invalid file path!")
return
default_out = Path(input_pdf).stem + "_watermarked.pdf"
output_pdf = input(f"Output PDF name [{default_out}]: ").strip() or default_out
page_range = get_page_range()
if mode == "1":
# --- Text Watermark Settings ---
text = input("\nWatermark text (e.g. CONFIDENTIAL): ").strip() or "CONFIDENTIAL"
font_size = int(input("Font size (default 50): ").strip() or 50)
opacity = float(input("Opacity 0.0-1.0 (default 0.15): ").strip() or 0.15)
rotation = float(input("Rotation angle (default 45): ").strip() or 45)
print("\nColor options: 1=Gray 2=Red 3=Blue 4=Black")
color_choice = input("Choose color (default 1): ").strip() or "1"
colors = {
"1": (0.5, 0.5, 0.5),
"2": (0.8, 0.1, 0.1),
"3": (0.1, 0.1, 0.8),
"4": (0.0, 0.0, 0.0)
}
color = colors.get(color_choice, (0.5, 0.5, 0.5))
def watermark_func(w, h):
return create_text_watermark(
text, w, h,
font_size=font_size,
opacity=opacity,
rotation=rotation,
color=color
)
else:
# --- Image Watermark Settings ---
image_path = input("\nEnter image path (.png/.jpg): ").strip()
if not os.path.isfile(image_path):
print(" Invalid image path!")
return
opacity = float(input("Opacity 0.0-1.0 (default 0.2): ").strip() or 0.2)
scale = float(input("Image scale 0.1-1.0 (default 0.4): ").strip() or 0.4)
def watermark_func(w, h):
return create_image_watermark(
image_path, w, h,
opacity=opacity,
scale=scale
)
apply_watermark(input_pdf, output_pdf, watermark_func, page_range)
# ---- Batch Mode ----
elif mode == "3":
folder = input("\nEnter folder path containing PDFs: ").strip()
if not os.path.isdir(folder):
print(" Invalid folder!")
return
text = input("Watermark text (e.g. DRAFT): ").strip() or "DRAFT"
font_size = int(input("Font size (default 60): ").strip() or 60)
opacity = float(input("Opacity 0.0-1.0 (default 0.15): ").strip() or 0.15)
rotation = float(input("Rotation angle (default 45): ").strip() or 45)
def watermark_func(w, h):
return create_text_watermark(text, w, h,
font_size=font_size,
opacity=opacity,
rotation=rotation)
batch_watermark(folder, watermark_func)
else:
print(" Invalid choice.")
return
print("\n" + "="*55)
print(" All done! Your watermarked PDF(s) are ready.")
print("="*55 + "\n")
# ============================================================
# RUN
# ============================================================
if __name__ == "__main__":
main()
No comments:
Post a Comment