[reportlab-users] Patch: PIL images with ReportLab
Sam Hunter
shunter at dbsupply.com
Mon May 2 13:46:47 EDT 2005
Well, I dug a bit deeper, and found this comment in the pdfutils.py
-----------------------------
#########################################################################
#
# JPEG processing code - contributed by Eric Johnson
#
#########################################################################
# Read data from the JPEG file. We should probably be using PIL to
# get this information for us -- but this way is more fun!
# Returns (width, height, color components) as a triple
# This is based on Thomas Merz's code from GhostScript (viewjpeg.ps)
def readJPEGInfo(image):
"Read width, height and number of components from open JPEG file."
------------------------------
So, I took the plunge, and re-wrote a bunch of stuff. These changes
make it so that ReportLab handles PIL images whether they have been
modified or not. The readJPEGInfo(image) function is no longer used for
PILs. PILs are always put into the PDF document as a JPG so they are
small, and drawImage() will catch PILs without the need for the user to
save them to the harddisk or wrap them in StringIO.
I think these changes shouldn't alter the functionality of anything else.
If anyone is interested I can post more detailed information, but major
changes are below.
Sam
In pdfdoc.PDFImageXObject I added a new member function:
#-------------------------------------------------------------------------------
def loadImageFromImageReader(self, im):
"Extracts width, height, image mode, etc from ImageReader image"
self.width, self.height = im.getSize()
self.colorSpace = im.getcolorSpace()
#bitsPerComponent might be bad since black and white images have
only 1
#I'm not sure if it is really used anywhere however.. and seem
to default to 8
#in loadImageFromSRC(self, im)
self.bitsPerComponent = 8
zlib = import_zlib()
if not zlib: return
#default to jpeg type images from PIL
#raw = im.getRGBData()
#assert(len(raw) == self.width*self.height, "Wrong amount of
data for image")
self.streamContent =
pdfutils._AsciiBase85Encode(im.getJPEG())
self._filters = 'ASCII85Decode','DCTDecode' #'A85','DCT'
self.mask = None
print "Exiting loadImageFromImageReader"
#-------------------------------------------------------------------------------
Changed the first part of Canvas.drawImage() quite a bit..
#-------------------------------------------------
if(hasattr(image, "__class__")):
imtype = str(image.__class__).split(".")[0]
else:
imtype = None
if type(image) == type(''):
#filename, use it
name = _digester('%s%s' % (image, mask))
elif(imtype == 'PIL'):
#convert to ImageReader type
image = ImageReader(image)
rawdata = image.getRGBData()
name = _digester(rawdata+str(mask))
else:
rawdata = image.getRGBData()
name = _digester(rawdata+str(mask))
#--------------------------------------------------
And added two new functions to the ImageReader class to extend it's PIL
handling capabilities.
#-------------------------------------------------------------------------------
def getcolorSpace(self):
"Return one of the following color codes:"
"'DeviceGray', 'DeviceRGB', 'DeviceCMYK', None"
if sys.platform[0:4] == 'java':
#I'm not sure how to get color information from javax.imageio
#a quick search on google doesn't suggest anything quick and
painless.
return None
else:
#this is a PIL image, values should be "1", "L", "RGB", or "CMYK."
#"1" = black and white, "L" = gray scale
mode = self._image.mode
if mode in ('1','L'):
self._mode = 'DeviceGray'
return self._mode
if mode == 'RGB':
self._mode = 'DeviceRGB'
return self._mode
if mode == 'CMYK':
self._mode = 'DeviceCMYK'
return self._mode
#if it isn't one of these
return None
def getJPEG(self):
"Return a string with jpeg data in it"
from cStringIO import StringIO
f = StringIO()
self._image.save(f, format="JPEG")
return f.getvalue()
#-------------------------------------------------------------------------------
Robin Becker wrote:
>>
>>
> ..... so far as I remember we originally intended that the ImageReader
> class should be
> a reader only. We used PIL internally to do conversions. It was never
> intended that we knew
> anything about the images. That's why I feel reluctant to bring PIL
> "inside". Because
> of earlier assumptions the internal code feels able to reject PIL if
> the pil format option
> reveals the original image to be JPEG. I'm not an expert on PIL, but
> if PIL is a valid option
> then we need to know what conversions etc etc are valid. At present
> (in the SVN code) we're
> alllowing conversions based on the PIL mode and possibly wrongly have
> allowed the format to
> leak into the internals. Before we used PIL internally. Now you
> propose making PIL a valid
> image format. Suppose you read a JPEG using PIL and pass it into
> ImageReader. Do I believe the
> given PIL or can I revert to the original semantics and use the file
> as a standard JPEG.
More information about the reportlab-users
mailing list