Rotating Images in ReportLab

There are times when you want to rotate images or other objects in ReportLab while creating a PDF. For example, you might want to rotate an image by 45 degrees for watermarking purposes. Or you might need an image that runs vertically along one of the edges of the PDF.

You can rotate images by using ReportLab’s canvas methods or by using its higher level Flowables that you can find in the platypus. module. Let’s start by looking at how to do this with the canvas directly!


Rotating Images Using Canvas

Rotating images using the canvas is kind of confusing. The reason being that when you rotate the canvas, you may end up inadvertently rotating other elements on your canvas if you’re not careful.

Let’s take a look at the code:

# image_on_canvas.py

from reportlab.lib import utils
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas


def add_image(image_path):
    img = utils.ImageReader(image_path)
    img_width, img_height = img.getSize()
    aspect = img_height / float(img_width)

    my_canvas = canvas.Canvas("canvas_image.pdf",
                              pagesize=letter)
    my_canvas.saveState()
    my_canvas.rotate(45)
    my_canvas.drawImage(image_path, 150, 10,
                        width=100, height=(100 * aspect))
    my_canvas.restoreState()
    my_canvas.save()

if __name__ == '__main__':
    image_path = 'snakehead.jpg'
    add_image(image_path)

Here you use ReportLab’s utils function to extract the image’s width and height. Then you create the canvas and save its current state. This will allow you to modify the canvas from this point forward and then restore it later. If you’d like to have some text or shapes before the rotated image, you would put that code before the call to saveState().

After saving the canvas state, you can use the canvas’s rotate() method to rotate the canvas 45 degrees. Then you draw the image to the canvas. Finally you use restoreState() to restore the state back to what it was before you rotated it.

Note: When rotating the canvas, the x/y position is now at a 45 degree angle, so you will have to take that into account while positioning the image on your canvas.

When I ran this code, I ended up with a document that looked like this:

Rotated image with ReportLab

You can also download the PDF here.

Now let’s find out how to do the same thing using a Flowable!


Rotating Images Using the Image Flowable

Flowables are objects in ReportLab that come from their platypus module, which stands for Page Layout and Typography Using Scripts. This module is basically a high-level interface to the canvas methods that abstracts the drawing bits away and makes creating multipage documents much simpler.

The quickest way to create a rotated image using a Flowable in ReportLab is to subclass the Image Flowable. Let’s take a look!

from reportlab.lib.pagesizes import letter
from reportlab.platypus import Image, SimpleDocTemplate

class RotatedImage(Image):

    def wrap(self, availWidth, availHeight):
        height, width = Image.wrap(self, availHeight, availWidth)
        return width, height

    def draw(self):
        self.canv.rotate(45)
        Image.draw(self)

doc = SimpleDocTemplate("image_with_rotation.pdf", pagesize=letter)
flowables = []

img = RotatedImage('snakehead.jpg',
                   width=50, height=50
                   )
img.hAlign = 'CENTER'
flowables.append(img)
doc.build(flowables)

Here you subclass Image and override the wrap() and draw() methods. The main piece that you will care about is in the draw() method where you call self.canv.rotate(45). The Image class has its own canvas in it that you can manipulate. In this case, you tell it that you want to always draw the image at a 45 degree angle.

Next you create a document template and create an instance of RotatedImage. Then you tell the image to be centered on the page. Finally you build() the document.

When you run this code, you should see the following:

Rotated image with ReportLab Flowable

You can get the actual PDF here if you’d rather see the file.


Wrapping Up

Now you know how to rotate images using ReportLab. You learned how to rotate an image using the low-level canvas methods and you also learned how to rotate an Image Flowable. You can use this knowledge to rotate other kinds of objects as well. For example, you can rotate text and shapes using the same methodology. You will always be rotating the canvas to get the needed effect. Have fun and happy coding!

Want to learn more about working with PDFs in Python? Then check out my book:

ReportLab: PDF Processing with Python

Purchase now on Leanpub


Related Reading