Python से मौजूदा PDF में SVG वॉटरमार्क जोड़ें
svglib, ReportLab और pypdf से मौजूदा PDF में SVG वॉटरमार्क मिलाएँ। अपारदर्शिता, कटे पेज, घुमाव, बचा टेक्स्ट और ओवरले क्रम जाँचें।
इस पेज पर
Python में मौजूदा PDF पर SVG वॉटरमार्क लगाने के लिए SVG को ReportLab ड्रॉइंग में बदलें, छोटे PDF ओवरले पर रेंडर करें और pypdf से हर मूल पेज में मिलाएँ। हर पेज के दिखाई crop बॉक्स से ओवरले आकार और स्थिति निकालें तथा मिलाने से पहले पेज घुमाव सामान्य करें।
अपारदर्शी पेज बैकग्राउंड के ऊपर चिह्न दिखाना हो तो over=True लें। अर्धपारदर्शी चिह्न भी ऊपर रह सकता है। over=False में वही आर्टवर्क पुरानी सामग्री के नीचे जाता है और भरे पेज के पीछे छिप सकता है।
पूरा उदाहरण अपना SVG और तीन-पेज स्रोत PDF बनाता है। इसमें अलग पेज आकार, गैर-शून्य मूल-बिंदु वाला crop बॉक्स और घूमा पेज है। परिणाम नया PDF है; मूल फ़ाइल अलग रखें।
पहले दस्तावेज़ का काम चुनें
| शुरुआत | उपयोगी कार्यप्रवाह |
|---|---|
| मौजूदा PDF के हर पेज पर SVG चिह्न चाहिए | SVG ओवरले रेंडर करके पुराने पेजों में मिलाएँ, जैसा नीचे |
| नया PDF शुरू से बन रहा है | सीधे ReportLab SVG ड्रॉइंग कार्यप्रवाह लें |
| मौजूदा SVG में सही आर्टवर्क है | मूल वेक्टर स्रोत रखें; ट्रेसिंग ज़रूरी नहीं |
| लोगो केवल रास्टर है | पहले उपयुक्त आर्टवर्क, फिर PDF मर्ज अलग जाँचें |
pypdf वॉटरमार्क गाइड पेज के ऊपर और नीचे रखी सामग्री अलग बताती है। यहाँ “वॉटरमार्क” दिखाई चिह्न है; असली स्टैक क्रम over तय करता है। यह सुरक्षा चिह्न, छेड़छाड़-रोधी तरीका या हस्ताक्षरित दस्तावेज़ कार्यप्रवाह नहीं।
1. छोटे समर्थित SVG से शुरू करें
परीक्षण में दो भरे पाथ हैं: खुले केंद्र वाला त्रिकोणी फ़्रेम और तीन पट्टियाँ। दोनों पर fill-opacity="0.25" है। टेक्स्ट, फ़िल्टर, एम्बेडेड इमेज या बाहरी संसाधन नहीं।
सीमित इनपुट महत्वपूर्ण है। svglib उपयोगी SVG उपसमूह लेता है, लेकिन उसकी दस्तावेज़ित सीमाओं में सीमित CSS और मास्क तथा foreignObject जैसे असमर्थित गुण हैं। ब्राउज़र में सही SVG भी परिवर्तन के बाद जाँचें। रास्टर हो तो पूरा वेक्टर मानने से पहले SVG में एम्बेडेड इमेज ढूँढना पढ़ें।
पहले नमूने में फ़्रेम के साथ SVG टेक्स्ट भी था। जाँचे स्टैक में बदला टेक्स्ट पूरी अपारदर्शिता से रंगा, जबकि पाथ 0.25 रहा। मैंने टेक्स्ट की जगह मूल पाथ आर्टवर्क रखा और फिर जाँचा। अंतिम परिणाम इसी केवल-पाथ मामले को स्थापित करता है, हर SVG टेक्स्ट या स्टाइल की सही अपारदर्शिता नहीं।
2. पूरा उदाहरण चलाएँ
जाँचा वातावरण Python 3.12.14, svglib 2.2.0, ReportLab 4.4.9 और pypdf 6.10.0 था। वर्तमान pypdf दस्तावेज़ नए संस्करण भी बताता है, इसलिए परीक्षण और दस्तावेज़ संस्करण अलग रखें।
अलग वातावरण में ये संस्करण लगाएँ:
python -m venv .venv
source .venv/bin/activate
python -m pip install svglib==2.2.0 reportlab==4.4.9 pypdf==6.10.0अगला कोड watermark_demo.py सहेजें। इसमें सारा इनपुट आर्टवर्क है और तीनों PDF बनते हैं, इसलिए कोई नमूना PDF या SVG डाउनलोड बाकी नहीं।
from io import BytesIO
from pathlib import Path
from pypdf import PdfReader, PdfWriter, Transformation
from pypdf.generic import RectangleObject
from reportlab.graphics import renderPDF
from reportlab.lib.colors import HexColor
from reportlab.pdfgen import canvas
from svglib.svglib import svg2rlg
SVG = '''<svg xmlns="http://www.w3.org/2000/svg" width="240" height="80"
viewBox="0 0 240 80">
<path fill="#315d6f" fill-opacity="0.25" fill-rule="nonzero"
d="M10 60 L45 8 L80 60 Z M31 48 L59 48 L45 27 Z"/>
<path fill="#315d6f" fill-opacity="0.25"
d="M95 23 H216 V31 H95 Z M95 39 H190 V47 H95 Z
M95 55 H205 V63 H95 Z"/>
</svg>'''
def make_demo_source(destination):
stream = BytesIO()
document = canvas.Canvas(stream, pagesize=(420, 300))
specifications = [
(420, 300, '#f5eddb', 'SOURCE PAGE ONE'),
(300, 420, '#ffffff', 'SOURCE PAGE TWO'),
(360, 260, '#e8eef0', 'SOURCE PAGE THREE')
]
for width, height, background, label in specifications:
document.setPageSize((width, height))
document.setFillColor(HexColor(background))
document.rect(0, 0, width, height, fill=1, stroke=0)
document.setFillColor(HexColor('#183a42'))
document.setFont('Helvetica-Bold', 16)
document.drawString(28, height - 40, label)
document.setFont('Helvetica', 10)
document.drawString(28, height - 62, 'Original text remains in the PDF content.')
document.drawString(28, 28, 'Original vector line and opaque page background')
document.setStrokeColor(HexColor('#c47b44'))
document.setLineWidth(3)
document.line(28, 48, width - 28, 48)
document.showPage()
document.save()
reader = PdfReader(stream)
reader.pages[1].cropbox = RectangleObject([10, 20, 290, 400])
reader.pages[2].rotate(90)
writer = PdfWriter()
for page in reader.pages:
writer.add_page(page)
writer.write(destination)
def make_overlay(svg_path, width, height):
drawing = svg2rlg(str(svg_path))
if drawing is None or drawing.width <= 0 or drawing.height <= 0:
raise ValueError('The SVG did not produce a usable drawing')
scale = width * 0.65 / drawing.width
left = (width - drawing.width * scale) / 2
bottom = (height - drawing.height * scale) / 2
drawing.scale(scale, scale)
stream = BytesIO()
overlay = canvas.Canvas(stream, pagesize=(width, height))
renderPDF.draw(drawing, overlay, left, bottom)
overlay.save()
return PdfReader(stream).pages[0]
def add_artwork(source_path, svg_path, output_path, *, over):
reader = PdfReader(source_path)
if reader.is_encrypted:
raise ValueError('Encrypted inputs are outside this example')
if reader.get_fields():
raise ValueError('Form handling is outside this example')
writer = PdfWriter()
writer.clone_document_from_reader(reader)
# Cloning in pypdf 6.10.0 does not retain the source header version.
# This overlay uses transparency, introduced in PDF 1.4.
writer.pdf_header = max(reader.pdf_header, '%PDF-1.4')
for page in writer.pages:
if page.rotation:
page.transfer_rotation_to_content()
box = page.cropbox
width, height = float(box.width), float(box.height)
overlay = make_overlay(svg_path, width, height)
page.merge_transformed_page(
overlay,
Transformation().translate(float(box.left), float(box.bottom)),
over=over,
expand=False
)
writer.write(output_path)
if __name__ == '__main__':
output = Path('watermark-output')
output.mkdir(exist_ok=True)
artwork = output / 'emblem.svg'
artwork.write_text(SVG)
source = output / 'source.pdf'
make_demo_source(source)
add_artwork(source, artwork, output / 'overlay-top.pdf', over=True)
add_artwork(source, artwork, output / 'underlay.pdf', over=False)इसे चलाएँ:
python watermark_demo.pywatermark-output/source.pdf, overlay-top.pdf और underlay.pdf खोलें। पहले पेज में ऊपरी ओवरले वाले परिणाम में चिह्न दिखे और निचले वाले में छिपे, क्योंकि मूल बैकग्राउंड अपारदर्शी है। बाकी पेज समान ज्यामिति दोहराने के बजाय crop और rotation जाँचते हैं।
अपने सामान्य बिना-हस्ताक्षर PDF में make_overlay() और add_artwork() रखें, फिर बुलाएँ:
add_artwork(
Path("original.pdf"),
Path("emblem.svg"),
Path("watermarked.pdf"),
over=True
)पारदर्शिता के कारण writer स्रोत header संस्करण रखता है, न्यूनतम PDF 1.4। pypdf 6.10.0 में केवल दस्तावेज़ clone करना डिफ़ॉल्ट PDF 1.3 header छोड़ सकता है, भले स्रोत नया हो। स्पष्ट assignment यह गिरावट रोकता है; अनुरूपता सत्यापन नहीं। Writer header दस्तावेज़ सभी उपयोग सुविधाओं का समर्थन करने वाला संस्करण सुझाता है।
सुरक्षा जाँच encrypted इनपुट और मिले form fields नकारती है। पूर्ण संगतता या हस्ताक्षर ऑडिट नहीं। हस्ताक्षरित दस्तावेज़, फ़ॉर्म, टिप्पणी, encryption और विशेष आवश्यकताओं के लिए कार्य फ़ाइल बदलने से पहले अलग प्रक्रिया और सत्यापन चाहिए।
3. दिखाई पेज निर्देशांकों में आर्टवर्क रखें
PDF पॉइंट 1/72 इंच है। इस svglib में SVG के बिना इकाई 240 × 80 आयाम 180 × 60-पॉइंट ड्रॉइंग बनाते हैं: एक CSS पिक्सेल 0.75 पॉइंट है। कोड SVG पिक्सेल को सीधे PDF पॉइंट मानने के बजाय drawing.width और drawing.height पढ़ता है।
उदाहरण SVG व्यूपोर्ट हर दिखाई पेज की चौड़ाई का 65% बनाता, अनुपात रखता और उस व्यूपोर्ट को केंद्रित करता है। घोषित आयत केंद्रित है, चिह्न का दृश्य भार नहीं। 65% उदाहरण लेआउट चुनाव है, वॉटरमार्क मानक नहीं। केवल चौड़ाई वाला स्केल दिखाए चौड़े चिह्न के लिए उचित है। लंबा विकल्प ऊँचाई से बाहर जा सकता है; फ़ंक्शन अपनाते समय उपलब्ध चौड़ाई और ऊँचाई दोनों से स्केल बाँधें और अपने PDF से पहले हर पेज देखें।
| पेज | स्रोत स्थिति | परिणाम का दिखाई crop बॉक्स, पॉइंट में | नाममात्र SVG व्यूपोर्ट चौड़ाई |
|---|---|---|---|
| 1 | 420 × 300 क्षैतिज पेज | 0, 0 से 420, 300 | 273pt |
| 2 | 300 × 420 पेज, भीतर crop | 10, 20 से 290, 400 | 182pt |
| 3 | 90° घूमा 360 × 260 पेज | सामान्य करने के बाद 0, 0 से 260, 360 | 169pt |
transfer_rotation_to_content() घुमाव कंटेंट और पेज बॉक्स में ले जाता है। दर्शक के सापेक्ष मूल शब्द सीधे नहीं करता। तीसरे पेज का टेक्स्ट स्रोत के दिखाई दृश्य जैसी दिशा में रहता है, नया चिह्न सामान्यीकृत दिखाई निर्देशांक में आता है। pypdf पेज API मर्ज से पहले घुमाव ले जाने की सलाह देता है।
ओवरले अपने मूल-बिंदु से शुरू है। उसे cropbox.left और cropbox.bottom से खिसकाना crop बॉक्स शून्य से अलग हो तब भी लक्ष्य के दिखाई क्षेत्र में रखता है। expand=False पेज बॉक्स बढ़ने से रोकता है।
4. केवल SVG प्रीव्यू नहीं, सहेजा PDF जाँचें

मैंने सहेजे PDF फिर खोलकर content streams, page boxes, rotation, निकाला टेक्स्ट और image resources देखे, फिर Poppler 26.02 से 96dpi पर दिखाई crop बॉक्स रेंडर किए। अंतिम निरीक्षण में 40 जाँचें सही थीं। ब्राउज़र तुलना ने हैश, लोड रेंडर और 12 मूल-रिज़ॉल्यूशन पिक्सेल जाँच भी पुष्ट कीं।
| इस उदाहरण की जाँच | देखा परिणाम |
|---|---|
| पेज संख्या और ज्ञात मूल टेक्स्ट | दोनों परिणाम में तीन पेज और अपेक्षित स्रोत टेक्स्ट रहे |
| ओवरले ज्यामिति | दो भरे पाथ, 18 जाँचे शीर्ष, हर पेज nonstroking अल्फ़ा 0.25 |
| जोड़े इमेज संसाधन | इन मूल स्रोत और परिणाम पेजों में कोई नहीं |
| स्थिति और पेज बॉक्स | घोषित crop और सहेजे transform गणना से मिले; परिणाम rotation शून्य |
| फ़्रेम और खुले केंद्र के नमूने | ऊपरी फ़्रेम पिक्सेल अपेक्षित मिश्रण से ±2 RGB में मिले; खुले केंद्र पर पेज बैकग्राउंड |
| अपारदर्शी बैकग्राउंड पर निचला ओवरले | पहले पेज के स्रोत और निचले रेंडर में 96dpi पर शून्य पिक्सेल अंतर |
स्थिति ऑडिट पहले 0.00001pt टॉलरेंस पर आदर्श floating-point तुलना में असफल था। ReportLab transform matrices सीमित precision में लिखता है। मैंने असफल परिणाम रखा, अपेक्षित सहेजे matrices और rounding bound स्वतंत्र निकाले और सहेजे शीर्ष उनसे मिलाए। सबसे बड़ा आदर्श निर्देशांक अंतर लगभग 0.000054pt था, निकली 0.000086pt सीमा के भीतर। यह इन फ़ाइलों में दृश्य केंद्रित स्थिति जाँचता है, सार्वभौमिक precision गारंटी नहीं।
Poppler लगा हो तो जल्दी स्थानीय दृश्य जाँच के लिए:
pdftoppm -cropbox -r 96 -png watermark-output/overlay-top.pdf watermark-output/top
pdftoppm -cropbox -r 96 -png watermark-output/underlay.pdf watermark-output/belowहर पेज उपयोगी ज़ूम पर देखें। अपेक्षित टेक्स्ट चुनें या निकालें, आयाम देखें और पता करें कि वॉटरमार्क पाथ रहा या इमेज बना। साफ़ स्क्रीनशॉट अकेला ये गुण नहीं बताता। परीक्षण ने छपाई, viewer संगतता, फ़ाइल आकार बचत या वॉटरमार्क हटाने का प्रतिरोध नहीं मापा।
सही चरण पर समस्या सुधारें
| लक्षण | क्या जाँचें या बदलें |
|---|---|
| चिह्न गायब | over=False और over=True मिलाएँ; अपारदर्शी मूल बैकग्राउंड देखें |
| crop पेज पर गलत जगह | तय पेज आकार के बजाय crop बॉक्स का आकार और मूल-बिंदु लें |
| घूमे पेज पर चिह्न अनचाही दिशा | दिखाई आयाम निकालने से पहले घुमाव सामान्य करें; परिणाम देखें |
| अपारदर्शिता या स्टाइल बदले | SVG सरल करें, बदले PDF की रंगाई स्थिति देखें और वही फ़ाइल जाँचें |
| फ़ोटो जैसा या पिक्सेल वाला भाग बचे | SVG में एम्बेडेड इमेज देखें; SVG खोल बिटमैप को पाथ नहीं बनाता |
| टेक्स्ट, फ़ॉर्म या व्यवहार बदले | सफल मर्ज सब बचाता है मानने के बजाय रुककर दस्तावेज़ की वास्तविक सुविधाएँ सत्यापित करें |
मूल PDF पेज कंटेंट रहता है; स्क्रिप्ट पूरे पेज रास्टर नहीं करती। इससे हर इनपुट मनमाने मर्ज में समान बचेगा यह साबित नहीं। कॉपी लें और बड़ा बैच करने से पहले तय करें कि कौन-सा कंटेंट और व्यवहार चलना चाहिए।
मर्ज से पहले छूटा आर्टवर्क तैयार करें
लोगो पहले से साफ़ SVG हो तो रखें। केवल उपयुक्त सपाट रास्टर बचा हो तो PerfectVector लोगो वेक्टराइज़र Python से पहले संपादन योग्य आर्टवर्क बना सकता है। मिली सिलुएट, छेद और छोटे विवरण देखें, फिर SVG परिवर्तन और सहेजा-PDF जाँच दोहराएँ। यहाँ मूल पाथ थे, PerfectVector परिवर्तन नहीं। वेक्टराइज़ेशन पेज नहीं मिलाता, हस्ताक्षर नहीं जाँचता या svglib संगतता नहीं देता।
अक्सर पूछे जाने वाले सवाल
क्या pypdf SVG वॉटरमार्क सीधे पढ़ सकता है? इस उदाहरण में पहले svglib और ReportLab से SVG का PDF ओवरले बनता है। फिर pypdf PDF कंटेंट मिलाता है; इस प्रक्रिया में SVG स्रोत नहीं समझता।
PDF पेज के पीछे वॉटरमार्क क्यों छिपता है?
मौजूदा अपारदर्शी बैकग्राउंड निचला ओवरले ढक सकता है। दिखाई ऊपर के लिए over=True और आर्टवर्क अपारदर्शिता अलग सेट करें। हर पेज का असली परिणाम देखें।
क्या वेक्टर आर्टवर्क और मूल टेक्स्ट बचते हैं? जाँचा केवल-पाथ चिह्न भरे पाथ रहा और तीनों पेज का अपेक्षित टेक्स्ट निकाला जा सका। उदाहरण से बाहर SVG और PDF सुविधाएँ अलग जाँचें।
PDF फिर लिखने से डिजिटल हस्ताक्षर बचेगा? इसे हस्ताक्षरित दस्तावेज़ का कार्यप्रवाह न लें। यह फ़ाइल फिर लिखता है और हस्ताक्षर बचना या वैधता नहीं जाँचता। हस्ताक्षरित मूल रखें और उसकी आवश्यकताओं वाला तरीका लें।
स्रोत
- pypdf: स्टैम्प या वॉटरमार्क जोड़ना — ऊपर-नीचे क्रम, मर्ज और rotation निर्देश।
- pypdf: PageObject API — पेज बॉक्स, rotation transfer और transformed merge।
- svglib प्रोजेक्ट दस्तावेज़ — SVG-से-ReportLab, इकाइयाँ और सीमाएँ।
- ReportLab ग्राफ़िक्स गाइड — ड्रॉइंग ऑब्जेक्ट और PDF रेंडर।
- pypdf 6.10.0: PDF header संस्करण — परिणाम सुविधाओं का समर्थन करने वाला संस्करण घोषित करना।
मूल आर्टवर्क हो तो रखें। केवल उपयुक्त रास्टर लोगो बचे तो PerfectVector से संपादन योग्य SVG बनाएँ, आर्टवर्क देखें और नया मर्ज PDF अलग सत्यापित करें।
Blog से और

fpdf2 SVG इमेज: Python PDF में पाथ सुरक्षित रखें
fpdf2 से Python PDF में SVG लोगो रखें, आकार नियंत्रित करें, सेव किए पाथ जाँचें और रास्टर विकल्प से पहले गायब टेक्स्ट या आकृतियों की वजह खोजें।

PDFKit SVG: वेक्टर लोगो को पिक्सेल बनाए बिना रखें
PDFKit दस्तावेज़ में पूरा SVG लोगो डालें, पॉइंट में आकार सेट करें और सेव PDF में पाथ, खुले हिस्से, गायब सुविधाएँ तथा एम्बेडेड इमेज जाँचें।
