ReportLab与Python Imaging Library内存中图像问题
我遇到了一个问题,搞不清楚怎么用PIL和reportlab一起工作。具体来说,我想在reportlab的画布上用drawImage来插入一个PIL的图像对象。
以前我通过原始数据、StringIO和reportlab的ImageReader类从网上插入图片到reportlab文档中。不过,ImageReader需要一个文件名或者类似文件的对象。
我的最终目标是把二维码(这些是PIL对象)放进reportlab生成的PDF里。有一种方法是这样的:
size, qrcode = PyQrcodec.encode('http://www.google.com')
qrcode.save("img.jpeg")
self.pdf.drawImage(ImageReader("img.jpeg"), 25, 25, width=125, height=125)
self.pdf.showPage()
这个方法是先保存图片,然后再把它读进PDF里。显然,这样做不太合理。
我遇到的困难还因为reportlab的发展历史比较长,找最新版本(2.4)相关的答案比较麻烦。
谢谢大家的帮助。
(顺便说一下,我用的是1.1.6版本的PIL)
4 个回答
奇怪的是,文档上说 drawImage 和 drawInlineImage 的工作方式是一样的,但实际上 drawInlineImage 可以直接用,而 drawImage 却不行。
查看ReportLab 2.4的源代码,似乎ImageReader可以把PIL图像对象当作“文件名”来使用。
def _isPILImage(im):
try:
return isinstance(im,Image.Image)
except ImportError:
return 0
class ImageReader(object):
"Wraps up either PIL or Java to get data from bitmaps"
_cache={}
def __init__(self, fileName):
if isinstance(fileName,ImageReader):
self.__dict__ = fileName.__dict__ #borgize
return
#start wih lots of null private fields, to be populated by
#the relevant engine.
self.fileName = fileName
self._image = None
self._width = None
self._height = None
self._transparent = None
self._data = None
if _isPILImage(fileName):
self._image = fileName
self.fp = getattr(fileName,'fp',None)
try:
self.fileName = self._image.fileName
except AttributeError:
self.fileName = 'PILIMAGE_%d' % id(self)
虽然看起来应该可以正常工作,但实际上并没有。我终于找到了问题所在,问题出在 _isPILImage() 这个函数里。问题是“Image.Image”实际上是“from PIL import Image”,而我的对象其实只是从 Image 导入的。我本来以为它们是一样的,但无论如何,isinstance 并不把它们当作相同的东西。我的临时解决办法是把 _isPILImage(fileName): ... 改成
519 def _isPILImage(im):
520 import Image as PIL_Image
521 try:
522 return isinstance(im,Image.Image) or isinstance(im, PIL_Image.Image)
523 except ImportError:
524 return 0
这样就解决了我的错误。因为你给了我正确的方向,我本来想把这个作为评论发出去,然后接受你的回答,但字符数不够。
谢谢你的建议!如果你能想到更优雅的解决办法……(我试着把 Image.Image 对象包装成一个 PIL Image 对象)请告诉我!