[reportlab-users] Reportlab and PIL images

Sam Hunter shunter at dbsupply.com
Tue Apr 26 12:01:06 EDT 2005

Hi, I'm just getting started with Reportlab, and I've run into a problem. 
I am trying to write an application which stores images in a pdf for 
possible later printing.
I would like to be able to resize these images without distortion (same 
HxW ratio) so that they fit on a page.  To do this I need height and 
width before I write the image to the canvas.

What I would like to do, is use the PIL image to load and resize, then 
stick the PIL image onto the canvas like this:

from reportlab.pdfgen import canvas
from PIL import Image
 filename = "test.pdf"
 c = canvas.Canvas(filename, pagesize=letter) #create a canvas of letter 
    width, height = letter
    c.rect(5, 5, width - 10, height - 10, fill=0)
    Im = Image.open("Spring-Mailer-front-1.jpg")
    xsize, ysize = Im.size
    if(xsize > ysize):  #deal with cases were xsize is bigger than ysize
      if(xsize > width):
        nxsize = width - 12
        nysize = int(ysize*(nxsize/xsize))  #make ysize
        xsize = nxsize
        ysize = nysize
        Im = Im.resize((nxsize, nysize))
    else:  #deal with cases where ysize is bigger than xsize
      if(ysize > height):
        nysize = height -12
        a = nysize/ysize
        nxsize = xsize * a
        xsize = int(nxsize)
        ysize = int(nysize)
        print "nxsize=%s, nysize=%s" % (nxsize, nysize)
        Im = Im.resize((nxsize, nysize))
    c.drawImage(Im, 6,5)

This always gives me an error  "AttributeError : Image instance has no 
attribute 'getRGBData'
                                                  c.drawImage(Im, 6, 5)
                                                  canvas.py:rawdata = 

Which is odd because in the ReportLab userguide.pdf it says that 
drawImage() should take PIL images

-------userguide.pdf: page 14----------------
canvas.drawImage(self, image, x,y, width=None,height=None,mask=None)
The arguments and return value work as for drawInlineImage. However, we 
use a caching system; a
given image will only be stored the first time it is used, and just 
referenced on subsequent use. If you supply
a filename, it assumes that the same filename means the same image. If 
you supply a PIL image, it tests if the
content has actually changed before re-embedding.

If I use the same code as above, except use

c.drawInlineImage(Im, 6, 5)
instead of
c.drawImage(Im, 6, 5)

  The code works perfectly, handles the PIL image without complaint, and 
produces a nice looking PDF.  The one problem is that the jpg 
compressions seems to get lost, and the file is 890k instead of 200k.  I 
am writing this code as part of a document management system which will 
eventually need to store millions of documents, so this larger size is a 
major problem.
  I have looked into turning on compression within the PDF document, but 
the documentation says that images are ALWAYS compressed

-------userguide.pdf: page 11----------------
The pageCompression option determines whether the stream of PDF 
operations for each page is
compressed. By default page streams are not compressed, because the 
compression slows the file generation
process. If output size is important set pageCompression=1, but remember 
that, compressed documents
will be smaller, but slower to generate. Note that images are always 
compressed, and this option will only
save space if you have a very large amount of text and vector graphics 
on each page.

So am I missing something here?  Is this a limitation in the Reportlab 


Sam Hunter

More information about the reportlab-users mailing list