Image aspect ratio using Reportlab in Python
Question: 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()
    


Answer: 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](http://i.stack.imgur.com/0EN8O.png)

