Reputation: 11
I'm using ReportLab to create a PDF page in python. This created page contains a single line of text. I want this line to become unselectable in the PDF. How can I achieve this?
Here is a sample code of how I create the page with a single line.
from StringIO import StringIO
from reportlab.pdfgen import canvas
...
buffer = StringIO()
canvas = canvas.Canvas(buffer)
canvas.drawString(30, 30, "Hello world!")
canvas.save()
...
In the generated PDF, Hello World!
will be selectable by the PDF viewer, which is undesirable. How to avoid it? I must output a string that will be different every time I run the program, so drawing a static image is not a solution.
Upvotes: 0
Views: 1465
Reputation: 11
As K J suggested, a feasible solution is to convert the line of text into an image, and render the image. The drawback is that the rendered text has limited quality, since it is not scalable. (A SVG cannot be used since it will retain the string, and it will be selectable in the PDF.)
Here is a sample code of how to make this conversion, using PIL. It presumes the text will be rendered in black.
from reportlab.graphics import renderPM
from reportlab.graphics.shape import Drawing, String
from reportlab.lib.utils import ImageReader
from PIL import Image
def drawString(canvas, x, y, string, dpi=72):
shape = String(0, 0, string)
s_x, s_y, s_width, s_height = shape.getBounds()
shape.y -= s_y # correct positioning
drawing = Drawing(s_width, s_height)
drawing.add(shape)
image = drawToPIL(drawing, dpi=dpi)
# Convert image background to transparent
image = image.convert("RGBA")
data = image.getdata()
new_data = []
for item in data:
tone = item[0]
new_data.append((0, 0, 0, 255 - tone))
image.putdata(new_data)
# render image into canvas
canvas.drawImage(ImageReader(image), x, y + s_y,
width=s_width, height=s_height, mask='auto')
(I must notice that I work with an old version of Report Lab, and I had to make some changes in the lib to make this work. Probably my workaround is not necessary in more recent versions.)
Upvotes: 1