【问题标题】:ReportLab and Python Imaging Library images from memory issue来自内存问题的 ReportLab 和 Python 成像库图像
【发布时间】:2010-02-09 07:41:17
【问题描述】:

我遇到了一个我似乎无法通过 PIL 和 reportlab 解决的问题。具体来说,我想使用 PIL Image 对象在 reportlab 的画布上使用 drawImage。

过去,我使用原始数据、StringIO 和 reportlab 的 ImageReader 类从网络将图像插入到 reportlab 文档中。不幸的是,ImageReader 采用文件名或文件缓冲区,如对象。

最终目标是能够将 QR 码(它们是 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)

【问题讨论】:

    标签: python python-imaging-library reportlab


    【解决方案1】:

    虽然它看起来应该可以工作,但实际上并没有。我终于能够找到问题所在,它在 _isPILImage() 函数中。问题是“Image.Image”实际上是“来自 PIL 导入 Image”,而我的对象实际上只是来自 Image。我会假设它们是相同的,但无论如何 isinstance 不会将它们评估为相同。我的 hack 解决方案是将 _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 对象中)让我知道!

    【讨论】:

    • 顺便说一下,上面的函数在reportlab的lib/utils.py中。
    • +1 好收获。 PIL 安装程序将 PIL 模块放在站点路径之外的 PIL 文件夹中是一个值得商榷的决定,但 ReportLab 依赖它会犯下更严重的错误。它应该只是导入图像。我通过从外部进行猴子修补解决了这个问题:自己导入图像,然后说reportlab.lib.utils.Image= Image
    • @bobince 在这里有正确的想法。 ReportLab 对 PIL 位置做了一些非常糟糕的假设,但在导入后使用 reportlab.lib.utils.Image=Image 进行修补比摆弄 ReportLab 代码并使部署复杂化要干净。
    • P.S.很棒的收获,@philipk!这是否已作为错误报告给 ReportLab?
    • 我不确定 - 我想我花了大约 20 分钟来尝试制作错误报告,但从未真正弄清楚如何去做。 (虽然不是正面的,那是很久以前的事了)
    【解决方案2】:

    查看 ReportLab 2.4 的源代码,似乎 ImageReader 将接受 PIL Image 对象作为“文件名”。

    
    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)
    

    【讨论】:

    • 所以self.pdf.drawImage(ImageReader(qrcode), 25, 25, width=125, height=125) 应该可以工作,假设drawImage 的其余参数是合适的。
    【解决方案3】:

    奇怪 文档声称 drawImage 和 drawInlineImage 的工作方式相同,但它可以与 drawInlineImage 一起工作,并且不能在 drawImage 中工作

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多