Skip to content

Instantly share code, notes, and snippets.

@bradleyayers
Created December 15, 2011 06:11
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bradleyayers/1480017 to your computer and use it in GitHub Desktop.
Save bradleyayers/1480017 to your computer and use it in GitHub Desktop.
Fill a page with an image with ReportLab and PIL
def fill_page_with_image(path, canvas):
"""
Given the path to an image and a reportlab canvas, fill the current page
with the image.
This function takes into consideration EXIF orientation information (making
it compatible with photos taken from iOS devices).
This function makes use of ``canvas.setPageRotation()`` and
``canvas.setPageSize()`` which will affect subsequent pages, so be sure to
reset them to appropriate values after calling this function.
:param path: filesystem path to an image
:param canvas: ``reportlab.canvas.Canvas`` object
"""
from PIL import Image
page_width, page_height = canvas._pagesize
image = Image.open(path)
image_width, image_height = image.size
if hasattr(image, '_getexif'):
orientation = image._getexif().get(274, 1) # 274 = Orientation
else:
orientation = 1
# These are the possible values for the Orientation EXIF attribute:
ORIENTATIONS = {
1: "Horizontal (normal)",
2: "Mirrored horizontal",
3: "Rotated 180",
4: "Mirrored vertical",
5: "Mirrored horizontal then rotated 90 CCW",
6: "Rotated 90 CW",
7: "Mirrored horizontal then rotated 90 CW",
8: "Rotated 90 CCW",
}
draw_width, draw_height = page_width, page_height
if orientation == 1:
canvas.setPageRotation(0)
elif orientation == 3:
canvas.setPageRotation(180)
elif orientation == 6:
image_width, image_height = image_height, image_width
draw_width, draw_height = page_height, page_width
canvas.setPageRotation(90)
elif orientation == 8:
image_width, image_height = image_height, image_width
draw_width, draw_height = page_height, page_width
canvas.setPageRotation(270)
else:
raise ValueError("Unsupported image orientation '%s'."
% ORIENTATIONS[orientation])
if image_width > image_height:
page_width, page_height = page_height, page_width # flip width/height
draw_width, draw_height = draw_height, draw_width
canvas.setPageSize((page_width, page_height))
canvas.drawImage(path, 0, 0, width=draw_width, height=draw_height,
preserveAspectRatio=True)
@dougbrowning
Copy link

dougbrowning commented Dec 30, 2019

Thanks a lot for this! I was having trouble getting full page images to work.

One issue though is that is is leaving a border and cropping some of the photo off. I added a -10 to all the page width to fake it and it seemed to work. I get a border still but no cropping at least.
draw_width, draw_height = page_width-10, page_height-10

Edit - I notice now that Google PDF and Adobe PDF reader are slightly different with the borders. It seems to be better on Adobe but I already added the -10. So it may be the reader?

Also the printer wants to scale it to 91%.

If there is a better way please let me know.

Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment