سؤال

I'm using python ReportLab canvas to generate overlay document with watermarks to merge it into source pdf document (with PyPDF2). Recently I encountered a problem with a document that contains rotated pages (/Rotate key is present for Page object in pdf). This document looks ok on devices and printers. But result (merged) document contains watermarks that were rotated against source document.

So source page has next structure in pdf:

6 0 obj
<</Length 45>>
stream
q
1 0 0 1 2 4 cm
799 0 0 603 0 0 cm
/x5 Do
Q

endstream
endobj
7 0 obj
<</Type/Page/Parent 1 0 R
/Resources << /XObject << /x5 5 0 R >> >>
/MediaBox [0 0 792 612]
/Rotate 270/Contents 6 0 R
>>
endobj

As you can see page rotated by 270 degrees.

I'm using similar script to generate and merge watermark and source page:

from six import BytesIO
from PyPDF2 import PdfFileWriter, PdfFileReader
from reportlab.lib.units import inch
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen.canvas import Canvas

# Set page rotation
rotation_angle = 270
# Render watermark layer
stream = BytesIO()
c = Canvas(stream, pagesize=A4)
if rotation_angle:
    c.setPageRotation(rotation_angle)
c.drawString(1 * inch, 8 * inch, "Hello World! " * 3)
c.showPage()
c.save()

stream.seek(0)
overlay = PdfFileReader(stream)
source = PdfFileReader(u'test.pdf')
writer = PdfFileWriter()

# Merge sorce and watermark pages
page0 = source.getPage(0)
if rotaion_angle:
    page0.mergeRotatedPage(overlay.getPage(0), rotation_angle, True)
else:
    page0.mergePage(overlay.getPage(0))
writer.insertPage(page0, 0)

# Write result to file
with open('merged.pdf', 'wb') as fp:
    writer.write(fp)
print "Done!"

This way for rotation_angle = 270 I've got next result: screenshot

And for rotation_angle = 0 (don't care about rotation at all) I've got: screenshot

How can I change script to fix this case?

هل كانت مفيدة؟

المحلول

Actually I found similar problem and solution here

So I changed code in next way

# Merge source and watermark pages
page0 = source.getPage(0)
over0 = overlay.getPage(0)
if rotaion_angle:
    page0.mergeRotatedAroundPointPage(
        over0,
        rotaion_angle,
        over0.mediaBox.getWidth() / 2,
        over0.mediaBox.getWidth() / 2)

    #page0.mergeRotatedPage(overlay.getPage(0), rotaion_angle, True)
else:
    page0.mergePage(over0)

Method mergeRotatedAroundPointPage do the trick.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top