2010-02-09 85 views
9

我遇到了一個問題,我似乎無法弄清楚PIL和reportlab。具體來說,我想使用PIL Image對象在reportlab中的畫布上使用drawImage。ReportLab和Python Imaging Library從內存問題的圖像問題

在過去,我使用原始數據,StringIO和reportlab的ImageReader類將圖像插入到來自Web的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)

回答

4

儘管它確實看起來應該起作用,但它確實沒有。我終於找到了問題,並且它在_isPILImage()函數中。問題是,「Image.Image」實際上是「從PIL導入圖像」,而我的對象實際上只是從圖像。我會假設它們是相同的,但無論如何,isinstance並不會將它們評估爲相同。我的黑客的解決辦法是改變_isPILImage(文件名):......到

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對象中)讓我知道!

+1

順便說一句,上面的函數在reportlab中的lib/utils.py中。 – philipk 2010-06-06 00:02:51

+3

+1好抓。 PIL安裝程序將PIL模塊放在站點路徑的PIL文件夾中是一個值得懷疑的決定,但ReportLab依靠它而犯了一個更嚴重的錯誤。它應該只是導入圖像。我通過從外部猴子修補來解決問題:import自己,並說'reportlab.lib.utils.Image = Image'。 – bobince 2011-01-18 00:13:15

+0

@bobince在這裏有正確的想法。 ReportLab對PIL位置做出了一些非常糟糕的假設,但在使用'reportlab.lib.utils.Image = Image'導入後修補會更乾淨,而不是擺弄ReportLab代碼並使部署複雜化。 – dkamins 2011-09-28 03:43:24

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) 
+0

所以'self.pdf.drawImage(ImageReader的(QR碼)工作, 25,25,width = 125,height = 125)'應該可以工作,假設'drawImage'的其餘參數是合適的。 – MattH 2010-02-09 11:01:55

0

weired 文檔聲稱的drawImage和drawInlineImage的工作方式相同,但它與drawInlineImage開箱的,不要在的drawImage