Align watermark horizontally in the middle in PDF?

Question:

i try to align a watermark in a pdf so it is exactly in the middle at the bottom with the following code:

from reportlab.pdfgen import canvas
from reportlab.lib.units import inch
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase.pdfmetrics import stringWidth

# text = "test test test"
text = "Peter Schmidt, Musterstraße 1, 50767 Köln"
pdf = canvas.Canvas("watermark.pdf", pagesize=A4)
pdf.translate(inch, inch)
pdf.setFillColor(colors.grey, alpha=0.6)
pdf.setFont("Helvetica", 15)
widthText = stringWidth(text, "Helvetica", 15) / 2
widthPage = pdf._pagesize[0]
x = (widthPage / 2) - (widthText / 2)
pdf.drawCentredString(x, -45, text)
pdf.save()

Generally it seems to work fine and when i use the text

text = "Peter Schmidt, Musterstraße 1, 50767 Köln"

it centers fine

enter image description here

but when i try it with a shorter text like

text = "test test test"

its not working anymore and the text is far to right

enter image description here

How can i solve this that the text is allways in the middle of the pdf?

Asked By: Rapid1898

||

Answers:

The issue here is that the horizontal Zero Position is not at the very left of the page but shifted right for some amount that serves as the left margin of the page. You need to find out, how big that margin is in order to calculate the correct position. If you are using a document template, that margin is defined somewhere in that template. I have not jet found a way to get the margin size programmatically without a template. But Using your code on my system appears to result in a left margin of 70.

With that information, the following code yields the desired result:

from reportlab.pdfgen import canvas
from reportlab.lib.units import inch
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase.pdfmetrics import stringWidth

text = "test test test"
#text = "Peter Schmidt, Musterstraße 1, 50767 Köln"
#text = "1"
pdf = canvas.Canvas("watermark.pdf", pagesize=A4)
pdf.translate(inch, inch)
pdf.setFillColor(colors.grey, alpha=0.6)
pdf.setFont("Helvetica", 15)
widthPage = pdf._pagesize[0]
leftMargin = 70     # acquired experimentally

# option 1 using drawCentredString()
x = (widthPage / 2) - leftMargin
pdf.drawCentredString(x, 0, text)

# option 2 using drawString()
widthText = stringWidth(text, "Helvetica", 15)
x2 = (widthPage / 2) - (widthText / 2) - leftMargin
pdf.drawString(x2, -45, text)

pdf.save()

The fact that you code worked for the long string was pure luck.
Note that the option using the drawCentredString() method does not need the width of the test at all.

The option using the drawString() method does need the width of the string. Note that the /2 is removed from the calculation of widthText to yield the correct width.

Answered By: Felix
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.