Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Image aspect ratio using Reportlab in Python

I want to insert an image inside a frame. I found two ways to do this:

  1. drawImage(self, image, x, y, width=None, height=None, mask=None, preserveAspectRatio=False, anchor='c')
  2. Image(filename, width=None, height=None)

My question is: how can I add an image in a frame while preserving its aspect ratio?

from reportlab.lib.units import cm
from reportlab.pdfgen.canvas import Canvas
from reportlab.platypus import Frame, Image

c = Canvas('mydoc.pdf')
frame = Frame(1*cm, 1*cm, 19*cm, 10*cm, showBoundary=1)

"""
If I have a rectangular image, I will get a square image (aspect ration 
will change to 8x8 cm). The advantage here is that I use coordinates relative
to the frame.
"""
story = []
story.append(Image('myimage.png', width=8*cm, height=8*cm))
frame.addFromList(story, c)

"""
Aspect ration is preserved, but I can't use the frame's coordinates anymore.
"""
c.drawImage('myimage.png', 1*cm, 1*cm, width=8*cm, preserveAspectRatio=True)

c.save()
like image 313
citn Avatar asked Mar 16 '11 15:03

citn


People also ask

How do I find the aspect ratio of an image in Python?

Integralist/aspect_ratio.py. def calculate_aspect(width: int, height: int) -> str: def gcd(a, b): """The GCD (greatest common divisor) is the highest number that evenly divides both width and height."""

Is ReportLab free?

ReportLab is a free open-source document creation engine for generating PDF documents and custom vector graphics.


1 Answers

You can use the original image's size to calculate its aspect ratio, then use that to scale your target width, height. You can wrap this up in a function to make it reusable:

from reportlab.lib import utils

def get_image(path, width=1*cm):
    img = utils.ImageReader(path)
    iw, ih = img.getSize()
    aspect = ih / float(iw)
    return Image(path, width=width, height=(width * aspect))

story = []
story.append(get_image('stack.png', width=4*cm))
story.append(get_image('stack.png', width=8*cm))
frame.addFromList(story, c)

Example using a 248 x 70 pixel stack.png:

enter image description here

like image 126
samplebias Avatar answered Sep 19 '22 03:09

samplebias