[reportlab-users] Patch: PIL images with ReportLab

Sam Hunter shunter at dbsupply.com
Thu Apr 28 12:23:28 EDT 2005


Okay I think we can have cake and eat it too.  With "ImageReader is the 
preferred  image type" idea in mind, how about just a small patch which 
detects if a PIL image is passed to drawImage(), and if so, wraps it in 
an ImageReader object which has the patch I previous posted.  This 
supports the idea of keeping ImageReader as the primary image type, 
allows PIL images to be used transparently, and streamlines things from 
the user's perspective.  I also don't think that it should cause a 
problem for Java related usage?

canvas.py,  drawImage(self, image, x, y, width=None, height=None, 
mask=None):
Original:
--------line 556-----------
        # first, generate a unique name/signature for the image.  If 
ANYTHING
        # is different, even the mask, this should be different.
        if type(image) == type(''):
            #filename, use it
            name = _digester('%s%s' % (image, mask))
        else:
            rawdata = image.getRGBData()
            name = _digester(rawdata+str(mask))
--------line 565----------

Modified:
--------line 28ish-------
from reportlab.lib.utils import ImageReader
------------------------
and
-------line 558ish------
        # first, generate a unique name/signature for the image.  If 
ANYTHING
        # is different, even the mask, this should be different.
        if(hasattr(image, "__class__")):
          imtype = image.__class__.__name__
        else:
          imtype = None
       
        if type(image) == type(''):
            #filename, use it
            name = _digester('%s%s' % (image, mask))
        elif(imtype == 'Image'): 
            #deal with PILs by wrapping them in ImageReader
            image = ImageReader(image)
            rawdata = image.getRGBData()
            name = _digester(rawdata+str(mask))

        else: 
            rawdata = image.getRGBData()
            name = _digester(rawdata+str(mask))
--------line



Also, the comment on line 1780 of pdfdoc.py should be changed to "it is 
already an ImageReader image", since the self.loadImageFromSRC does not 
seem to handle PIL images, and does handle ImageReader images.

pdfdoc.py,  PDFImageXObject.__init__()
Original:
---line 1779-----------
        else: # it is already a PIL Image
            self.loadImageFromSRC(source)
---line 1782------------

Modified:
---line 1779-----------
        else: # it is already an ImageReader Image
            self.loadImageFromSRC(source)
---line 1782------------



With these changes, and the one I posted earlier, I can load PIL images, 
use PIL routines on them, and then put them in PDF docs with the same 
ease that I can stick a standard JPG loaded from a file name into a PDF.

cheers,

Sam


Robin Becker wrote:

>
>
> The ImageReader object is the only nn filename image we're supposed to 
> be passing into the back end.  We should not be passing raw images 
> around and handling them with special case code everywhere. That's why 
> we have the _image thing inside it is supposed to be private. The 
> reason for the separate load from functions is that we have 
> potentially different sources.
>
> First off JPeg is native for PDF and is used even when PIL is not 
> available. Thus we have a fake attempt to split files on the extension 
> and use loadImageFromJPEG; converting a JPEG to RGB or CMYK is 
> non-trivial.
>
> For historical reasons we still attempt to support prebuilt .a85 files 
> which have been built into a PDF stream format in some way and are 
> available when PIL isn't that's via loadImageFromA85.
>
> Otherwise the path is via loadImageFromSRC (which should really be 
> called loadImageFromImageReader). If any encapsulation is to be done I 
> prefer that it be restricted to the ImageReader class.
>
> I strongly oppose removing the special JPEG handling. PIL doesn't 
> exist everywhere and we would be foolish to rely on it. The same is 
> true of attempts to get PIL to do the formatting into PDF.
>
> Allowing the ImageReader class to accept some specific image object 
> instances is fine.
>
> So far as I know we are using
>
> im.getSize
> im.getRGBData
> im.mode
>
> im.fp
> im.format
>
> I'm pretty sure the latter two are only used in a hackish attempt to 
> use a PIL opened JPEG in native form. The reason for that is as 
> follows; if we don't use the native version we have to do a conversion 
> to either RGB or CMYK etc. Of course if what you really want to do is 
> read a PIL image do conversions and then use the result via RGB 
> conversion then this hack is wrong.
>
> The real pain is that we currently have similar approaches in two 
> places ie pdfdoc.py/pdfutils and also pdfimages.



More information about the reportlab-users mailing list