2010-02-09 5 views
9

Я столкнулся с проблемой, которую я не могу понять с помощью PIL и reportlab. В частности, я хотел бы использовать drawImage на холсте в reportlab, используя объект PIL Image.ReportLab и изображения библиотеки изображений Python из памяти проблема

В прошлом я вставлял изображения в документы reportlab из Интернета, используя необработанные данные, StringIO и класс ImageReader Reportlab. К сожалению, ImageReader принимает имя файла или файловый буфер, такой как объект.

Конечная цель - разместить QR-коды (объекты PIL) в PDF-файлах reportlab. Одна вещь, которая делает работу, заключается в следующем:

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», тогда как мой объект на самом деле находится только из Image. Я бы предположил, что они были одинаковыми, но в любом случае isststance не оценивает их как одно и то же. Мой хак решение было изменить _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), дайте мне знать!

+1

Кстати, функция выше находится в lib/utils.py в reportlab. – philipk

+3

+1 хороший улов. Установщик PIL, устанавливающий модули PIL в папке PIL с пути сайта, является сомнительным решением, но ReportLab делает худшую ошибку, полагаясь на него. Он должен просто импортировать изображение. Я работал над проблемой путем обезглавливания снаружи: импортируйте изображение самостоятельно и произнося «reportlab.lib.utils.Image = Image». – bobince

+0

@bobince имеет правильную идею здесь. ReportLab делает некоторые действительно плохие предположения относительно местоположения PIL, но после импорта следует очищать его с помощью 'reportlab.lib.utils.Image = Image', чем использовать код ReportLab и усложнять развертывание. – dkamins

2

Глядя на источник 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) 
+0

Так 'self.pdf.drawImage (ImageReader (QRcode), 25, 25, width = 125, height = 125) 'должно работать, считая остальные аргументы' drawImage' подходящими. – MattH

0

weired документация утверждает, что DrawImage и drawInlineImage работают точно так же, но он работает с drawInlineImage из коробки, и не работают в DrawImage